Code Appendix
knitr::opts_chunk$set(fig.width=12, fig.height=8, fig.path='Figs/',
echo=FALSE, warning=FALSE, message=FALSE, cache = TRUE)
# Read in relevant libraries
library(microbenchmark)
library(data.table)
library(quantmod)
library(ggplot2)
library(tseries)
library(zoo)
library(magrittr)
library(dplyr)
library(kableExtra)
library(formattable)
library(quantreg)
library(MTS)
library(plot3D)
library(citr)
library(formattable)
# Set up working directory
# setwd("~/Documents/GitHub/CaviaR")
# source('caviar_SM.R')
source('~/Documents/GitHub/CaviaR/caviar_SM.R')
# This code below is for use in the CAViaR sections.
# Here is code that I'll wrap some parts in to avoid superfluous output
quiet <- function(x) {
sink(tempfile())
on.exit(sink())
invisible(force(x))
}
#' This is a function which pulls data for use in the CAViaR model
#'
#' @param symbol - symbol to pull
#' @param compl_case - defaults to true...only includes complete cases in the data
#' @param adj_close - use adjusted closing prices. Default is yes.
#' @param log_return - use log return? Default is yes.
#'
#' @return - a data frame which can be fed into later functions
#' @export
#'
#' @examples - data_pull("SPY")
data_pull = function(symbol, compl_case = 1, adj_close = 1, log_return = 1, start_date = "1900-01-01", end_date = Sys.Date()){
# Pull in data from quantmod
response_pull = getSymbols(symbol, auto.assign = FALSE, from = start_date, to = end_date)
# Get adjusted closing price
if (adj_close == TRUE){
df = Ad(response_pull)
} else {
df = Cl(response_pull)
}
# Return complete cases only
if (compl_case == TRUE){
df = df[complete.cases(df), ]
} else{
df = df
}
# Calculate log return of data
if (log_return == TRUE){
lr = log(df[,1]/shift(df[,1], 1, type = "lag"))
# Combine data
df_out = cbind(df, lr)
# Rename the data
colnames(df_out) <- c(sym=symbol, paste0(symbol, "_log_return"))
} else{
df_out = df
}
# Return data
return(df_out)
}
#' Pull the data and run the CAViaR function on it
#'
#' @param input_data - data to use in the function
#' @param range_data - range of the data to use
#'
#' @return - a list of values from the caviar function
#' @export
#'
#' @examples - caviar_pull(spy)
caviar_pull = function(input_data, range_data = (2:dim(input_data)[1])){
# Run the caviar data
caviar <- caviarOptim(input_data[range_data,2])
return(caviar)
}
#' Function for producing rolling predictions
#' Model 1 = Symmetric Absolute Value, 2 = Asymmetric slope, 3 = Indirect GARCH, 4 = Adaptive
#'
#' @param input_data - input data from the previous function
#' @param range_data - range of the data to consider
#' @param nfcst - number of forecasts to make
#' @param model - model to use (integers 1 through 4). Defaults to 1.
#' @param level - level of significance to use.
#' @param G - argument for the k parameter in the 4th model (adaptive). Default is 5
#'
#' @return - an xts object which contains rolling CAViaR predictions
#' @export
#'
#' @examples - rolling_predictions(spy, nfcst = 22)
rolling_predictions = function(input_data, range_data = (2:dim(input_data)[1]), nfcst = 250, model =1, level = 0.01, G = 5, col = 2){
# Run the varpredict function
varpredict <- rollapplyr(input_data[range_data,col], length(range_data) - nfcst, caviarOptim, model, level, predict = 1, k = G) %>% lag
# Eliminate NAs
# pred_no_na = na.omit(varpredict)
# Return the data
# return(pred_no_na)
return(varpredict)
}
#' Function to Calculate Loss from the above predictions
#'
#' @param symbol - symbol to work with from quantmod. Must be in quotations to work
#' @param start_dt - start date of the data to build the forecast on
#' @param end_dt - end date of the data to build the forecast on
#' @param nfcst - number of data points to use in the forecast
#' @param model - model to use. Defaults to 1
#' @param level - level of significance. Defaults to 1%
#' @param G - argument for the k parameter in the 4th model (adaptive). Default is 5
#'
#' @return - loss using absolute value
#' @export - a plot of the data
#'
#' @examples
loss_calc_uv = function(symbol, start_dt, end_dt, nfcst, model = 1, level = 0.01, G = 5){
# Pull in the data
raw_data = data_pull(symbol, start_date = start_dt, end_date = end_dt)
# Forecast based on the data
fcst = na.omit(rolling_predictions(raw_data, nfcst = nfcst, model = model, level = level, G = G))*(-1)
# Extract actuals
act = tail(raw_data, n = nfcst)[,2]
# Join the two together and rename
join = merge(fcst,act,all=TRUE)
colnames(join) <- c("Fcst_VaR", "Act_Return")
# print(join)
# Calculate the losses
loss = abs(sum(ifelse(act > fcst, level, (-1)*(1-level))))
# Plot the data
plot = plot.xts(join, col = c("red", "black"), lty = c(2,1), main = "Log Return from the SPY vs. Fcst. VaR",grid.col = NA, legend.loc = "bottomleft")
return(list(loss, plot, act, fcst))
}
#' This is a function which creates a data frame for the response and explanatory variables that we'll feed into the diffusion index
#'
#' @param symbol_list - a list of symbols recognizable by the
#' @param resp_var - the response variable we'd like to forecast; default is SPY
#' @param compl_case - defaults to true...only includes complete cases in the data
#' @param adj_close - use adjusted closing prices for the explanatory variables? default is 1 for YES
#' @param resp_adj_close - use adjusted closing prices for the explanatory variables? default is 1 for YES
#' @param start_date - starting data to use
#' @param end_date - ending date of the data
#' @param lag_pred - do we lag the predictions? It is STRONGLY recommended that this is 0
#'
#' @return - a data frame which can be fed into the SWfore function
#' @export
#'
#' @examples - diff_index_df(c("XLF", "XLE", "PSCT", "XLV", "VPU", "XLP", "IGF", "XWEB", "PPTY"))
diff_index_df = function(symbol_list, resp_var = "SPY", compl_case = 1, adj_close = 1, resp_adj_close = 1, start_date = "1900-01-01", end_date = Sys.Date(), lag_pred = 1){
# Pull in response variable
response_pull = getSymbols(resp_var, auto.assign = FALSE, from = start_date, to = end_date)
# Get adjusted closing price
if (resp_adj_close == TRUE){
diff_df = Ad(response_pull)
} else {
diff_df = Cl(response_pull)
}
# Loop through the symbols and join in data
for (i in 1:length(symbol_list)){
# Pull closing price
expl_pull = getSymbols(symbol_list[i], auto.assign = FALSE, from = start_date, to = end_date)
# Extract closing price - 4th element
if (adj_close == TRUE){
expl_cl = Ad(expl_pull)
} else {
expl_cl = Cl(expl_pull)
}
# New code for 4.16.2020 - lag the explanatory variables
if (lag_pred == TRUE){
# Lag the explanatory variables by 1
lag_exp = lag(expl_cl, 1)
# Append the first lag to the data frame
diff_df = merge(diff_df, lag_exp, join = "left", fill = NA)
} else{
# Return the data frame without lags
diff_df = merge(diff_df, expl_cl, join = "left", fill = NA)
}
}
if (lag_pred == TRUE){
# Chop off the first row
diff_df = diff_df[-1,]
}
else {
print("PLEASE NOTE - the explanatory variables in this DF are NOT lagged. Be careful to avoid look-ahead bias!")
}
# Return complete cases only
if (compl_case == TRUE){
diff_df_out = diff_df[complete.cases(diff_df), ]
} else{
diff_df_out = diff_df
}
return(diff_df_out)
}
#' Converts a diff_df into a data frame with approximate percentage changes diff(log(diff_df))
#'
#' @param diff_df - output of the diff_index_df function with complete cases
#'
#' @return - retuns the differenced data
#' @export
#'
#' @examples - pc_diff_index(test_compl)
pc_diff_index = function(diff_df){
# Difference the log of the data
pc_diff_index = diff(log(diff_df))
# Remove the first row
pc_diff_index_out = pc_diff_index[-1,]
return(pc_diff_index_out)
}
#' Below is the modified diffusion index code.
#'
#' @param y - response variable
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param m - number of diffusion indexes used
#' @param tau - VaR level to use; must be between 0 and 1
#' @param end - specifies an alternate ending value
#' @param print_mdl - print the model summary and the MSE
#'
#' @return - returns a list of variables for use in the diffusion index
#' @export
#'
#' @examples
mod_di = function (y, x, orig, m, tau, end = NULL, print_mdl = 0)
{
# Converts the response variables into a matrix
if (!is.matrix(x))
x = as.matrix(x)
# nT is number of t time-steps
nT = dim(x)[1]
# Add a line to establish the number of data points used in the test.
if (is.null(end) != TRUE){
nT = end
}
# k is the number of diffusion indices used
k = dim(x)[2]
# Sanity checks to ensure that the origin isn't past the number of time points
if (orig > nT)
orig = nT
# Makes sure that there aren't more predictors than there variables in the dataset
if (m > k)
m = k
# Makes sure there are at least some variables
if (m < 1)
m = 1
# Subdivides the dataframe
x1 = x[1:orig, ]
# Calculates means of each row
me = apply(x1, 2, mean)
# Calculates standard deviations of each column
se = sqrt(apply(x1, 2, var))
# Creates a matrix x1, which normalizes all the columns.
# This may be an issue since it assumes that the distribution is sufficiently described by the first two moments
x1 = x
for (i in 1:k) {
x1[, i] = (x1[, i] - me[i])/se[i]
}
V1 = cov(x1[1:orig, ])
# Performs an eigen decomposition
m1 = eigen(V1)
# Selects eigenvalues
sdev = m1$values
# Selects eigenvectors
M = m1$vectors
# Makes a smaller matrix
M1 = M[, 1:m]
# This is the diffusion index model - [orig x p]*[p x m] = [orig x m]
Dindex = x1 %*% M1
# Cut down both the response and predictors to be a reasonable size
y1 = y[1:orig]
DF = Dindex[1:orig, ]
# Apply the linear model - HERE is the key.
# mm = lm(y1 ~ DF) - old function
mm = rq(y1 ~ DF, tau = tau)
# Print the data
if (print_mdl == 1){
print(summary(mm))
}
# Puts coefficients in a matrix
coef = matrix(mm$coefficients, (m + 1), 1)
# Initializes yhat variables and MSE
yhat = NULL
MSE = NULL
if (orig < nT) {
# Creates a nfcst by (m+1) matrix
newx = cbind(rep(1, (nT - orig)), Dindex[(orig + 1):nT,
])
# [nfcstx(m+1)]*[(m+1)x1] = [nfcstx1]
yhat = newx %*% coef
# Calculates errors
err = y[(orig + 1):nT] - yhat
MSE = mean(err^2)
if (print_mdl == 1){
cat("MSE of out-of-sample forecasts: ", MSE, "\n")
}
}
SWfore <- list(coef = coef, yhat = yhat, MSE = MSE, loadings = M1,
DFindex = Dindex)
}
#' Below is the modified diffusion index code to include lagged variables.
#'
#' @param y - response variable
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param m - number of diffusion indexes used
#' @param tau - VaR level to use; must be between 0 and 1
#' @param ar_tf - AR transformation type. (1 - no transformation,
#' 2 - absolute value, 3 - asymmetric slope)
#' @param p - number of AR lags to include. Default is one.
#' @param print_mdl - option to print the model summary to make sure everytning is ok. 0 is default.
#' @param model - model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
#'
#' @return - returns a list of variables for use in the diffusion index
#' @export
#'
#' @examples
mod_di_wl = function (y, x, orig, m, tau, ar_tf = 1, p = 1, print_mdl = 0, model = 1, end = NULL)
{
# Converts the response variables into a matrix
if (!is.matrix(x))
x = as.matrix(x)
# nT is number of t time-steps
nT = dim(x)[1]
# Add a line to establish the number of data points used in the test.
if (is.null(end) != TRUE){
nT = end
}
# k is the number of diffusion indices used
k = dim(x)[2]
# Sanity checks to ensure that the origin isn't past the number of time points
if (orig > nT)
orig = nT
# Makes sure that there aren't more predictors than there variables in the dataset
if (m > k)
m = k
# Makes sure there are at least some variables
if (m < 1)
m = 1
# Subdivides the dataframe
x1 = x[1:orig, ]
# Calculates means of each row
me = apply(x1, 2, mean)
# Calculates standard deviations of each column
se = sqrt(apply(x1, 2, var))
# Creates a matrix x1, which normalizes all the columns.
# This may be an issue since it assumes that the distribution is sufficiently described by the first two moments
x1 = x
for (i in 1:k) {
x1[, i] = (x1[, i] - me[i])/se[i]
}
V1 = cov(x1[1:orig, ])
# Performs an eigen decomposition
m1 = eigen(V1)
# Selects eigenvalues
sdev = m1$values
# Selects eigenvectors
M = m1$vectors
# Makes a smaller matrix
M1 = M[, 1:m]
# This is the diffusion index model - [orig x p]*[p x m] = [orig x m]
Dindex = x1 %*% M1
# Cut down both the response and predictors to be a reasonable size
y1 = y[1:orig]
DF = Dindex[1:orig, ]
# Copy the data frame
DF_wl = Dindex
# Lag the y-variable
for (i in 1:p){
# Create a lagged variable
lag_var = lag(y, i)
# Append the first lag to the data frame
DF_wl = cbind(DF_wl,lag_var)
}
# Identify the right columns
l_ar = ncol(DF_wl)
f_ar = l_ar - p + 1
# Keep the last columns kept to the side
all_lag = DF_wl[,(f_ar:l_ar)]
# Cut off the first row to avoid NA's
DF_trim = DF_wl[1:orig,]
# Rename the columns
# Here's the new function with an untransformed AR(p) lag
if (ar_tf == 1){
# Incorporate everything in to an input data frame
df_in = cbind(y1[-(1:p)], DF_trim[-(1:p),])
# Rename the columns
# Initialize a character vector
nvec = c(rep(0, 1+m+p))
# Populate the vector - first value is the response
nvec[1] <- names(y)
# Next are the diffusion indices
for (i in 1:m){
nvec[i+1] = paste0("Diff_Index_", i)
}
# Next are the lagged variables
for (i in 1:p){
nvec[i+1+m] = paste0("Lag_", i)
}
# Assign the names
names(df_in) <- nvec
# Run the model
mm = rq(df_in[,1] ~ df_in[,-1], tau = tau)
}
# Here's the new function with an SAV AR(p) lag
if (ar_tf == 2){
# Incorporate everything in to an input data frame
df_in = cbind(y1[-(1:p)], DF_trim[-(1:p),-(f_ar:l_ar)], abs(DF_trim[-(1:p),(f_ar:l_ar)]))
# Rename the columns
# Initialize a character vector
nvec = c(rep(0, 1+m+p))
# Populate the vector - first value is the response
nvec[1] <- names(y)
# Next are the diffusion indices
for (i in 1:m){
nvec[i+1] = paste0("Diff_Index_", i)
}
# Next are the lagged variables
for (i in 1:p){
nvec[i+1+m] = paste0("Lag_", i)
}
# Assign the names. Note that this is a matrix
names(df_in) <- nvec
# Run the model
mm = rq(df_in[,1] ~ df_in[,-1], tau = tau)
}
# Here's the new function with an asymmetric slope for the AR(1) lag
# Indicator; 0 if percent change is negative, 1 if it's positive
# indi = ifelse(DF_trim[,ar] < 0, 0, 1)
if (ar_tf == 3){
# Create a matrix of indicators
indi_mat = matrix(0, nrow(DF_wl), p)
# Generalize the above code
for (i in 1:p){
# Populate the indicator
indi_mat[,i] = ifelse(DF_wl[,f_ar + i - 1] < 0, 0, 1)
}
}
# Fitting the regression
if (ar_tf == 3){
# Incorporate everything in to an input data frame
df_in = cbind(y1[-(1:p)], DF_trim[-(1:p),-(f_ar:l_ar)], DF_trim[-(1:p),(f_ar:l_ar)], indi_mat[((p+1):orig),])
# Rename the columns
# Initialize a character vector
nvec = c(rep(0, 1+m+2*p))
# Populate the vector - first value is the response
nvec[1] <- names(y)
# Next are the diffusion indices
for (i in 1:m){
nvec[i+1] = paste0("Diff_Index_", i)
}
# Next are the lagged variables
for (i in 1:p){
nvec[i+1+m] = paste0("Lag_", i)
}
# Last are the positive indicator variables
for (i in 1:p){
nvec[i+1+m+p] = paste0("Pos_Val_for_Lag_", i)
}
# Assign the names. Note that this is a matrix
names(df_in) <- nvec
# Run the model
mm = rq(df_in[,1] ~ df_in[,-1], tau = tau)
# mm = rq(y1[-(1:p)] ~ DF_trim[-(1:p),-(f_ar:l_ar)] + DF_trim[-(1:p),(f_ar:l_ar)] + indi_mat[((p+1):orig),], tau = tau)
# Add a different line to account for the indicator variable
# intercept + m + 2*nlag to account for the number of indicator variables
coef = matrix(mm$coefficients, (1 + m + 2*p), 1)
}
if (print_mdl == 1){
print(summary(mm))
}
# Puts coefficients in a matrix - added the AR terms
# coef = matrix(mm$coefficients, (m + 1), 1)
if (ar_tf != 3){
coef = matrix(mm$coefficients, (1 + m + p), 1)
}
# Initializes yhat variables and MSE
yhat = NULL
loss = NULL
if (orig < nT) {
# Creates a nfcst by (m+2) matrix
# Add on the lagged variables
newx = cbind(rep(1, (nT - orig)), Dindex[(orig + 1):nT, ], all_lag[(orig+1):nT,])
# Incorporate lagged variables
if (ar_tf == 3){
newx = cbind(rep(1, (nT - orig)), Dindex[(orig + 1):nT, ], all_lag[(orig+1):nT,], indi_mat[(orig+1):nT,])
}
# [nfcstx(m+1)]*[(m+1)x1] = [nfcstx1]
yhat = newx %*% coef
# Calculates errors
loss = abs(sum(ifelse(y[(orig + 1):nT] > yhat, tau, (-1)*(1-tau))))
# Modifying this part to only print this if specified
if (print_mdl == 1){
cat("Losses of out-of-sample forecasts: ", loss, "\n")
}
}
SWfore <- list(coef = coef, yhat = yhat, loss = loss, loadings = M1,
DFindex = Dindex, name_vector = nvec)
}
# Decide on the optimal number of vectors.
# (y, x, orig, m, tau)
#' Function that calculates loss over a given period of time for the diffusion index model
#'
#' @param y - response variables
#' @param x - explanatory variable
#' @param orig - forecast origin
#' @param end - forecasting ending. Note: as the function is currently written on 2/24, this option doesn't do anything.
#' @param m - number of diffusion indices to use
#' @param tau - VaR level
#' @param mod_di - use the modified DI?
#'
#' @return - returns a list of the loss sum and the loss vector
#' @export
#'
#' @examples - loss_calc(pc_df[,1], pc_df[,-1], 757, 1027, 1, 0.01)
loss_calc = function(y, x, orig, m, tau, mod_di = 0, ar_tf = 1, p = 1, print_mdl = 0, model = 1, end = NULL){
# Extract y_hat values
if (mod_di == 0){
di = mod_di(y=y,x=x,orig=orig,m=m, tau=tau, end = end, print_mdl = print_mdl)
}
else {
di = mod_di_wl(y=y,x=x,orig=orig,m=m, tau=tau, ar_tf = ar_tf, p = p, print_mdl = print_mdl, model = model, end = end)
}
# mod_di_wl = function (y, x, orig, m, tau, ar_tf = 1, p = 1, print_mdl = 0, model = 1)
yhat = di$yhat[1:(end-orig)]
# Calculate the loss
# Initialize loss vector
lvec = rep(0,(end-orig))
# Take the difference
for (i in 1:(end-orig)){
# Calculate an indicator variable
ind = ifelse(y[orig+i] < yhat[i], 1,0)
# Use indicator in function below
lvec[i] = (tau - ind)*(y[orig+i] - yhat[i])
}
# Add up the losses - change to look at sum of losses. Won't change decision criterion
sumloss = sum(lvec)
# sumloss = sum(lvec)/length(lvec)
return(list(sumloss,lvec))
}
#' Function that selects the optimal number of predictors
#'
#' @param y - response vector
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param end - ending of validation set
#' @param tau - VaR in question
#' @param low_m - low value of m to consider
#' @param high_m - high value of m to consider
#'
#' @return - returns the optimal value of m
#' @export
#'
#' @examples - opt_m(pc_df[,1], pc_df[,-1], 757, 1027, 0.01, low_m =1, high_m = 5)
opt_m = function(y, x, orig, end = NULL, tau, low_m = 1, high_m, mod_di = 0, ar_tf = 1, p = 1, print_mdl = 0, model = 1, rowname = NULL){
# Initialize a loss vector
loss_vec = rep(0,high_m-low_m + 1)
# Initialize an m vector
m_vec = seq(low_m, high_m, by = 1)
# Loop through and populate the loss vector
for (i in 1:length(loss_vec)){
loss_vec[i] = quiet(loss_calc(y=y,x=x,orig=orig,end=end, m = m_vec[i], tau = tau, mod_di = mod_di, ar_tf = ar_tf, p = p, print_mdl = print_mdl, model = model))[[1]]
}
# Find the minimizer
opt_m = which.min(loss_vec)
opt_p = NA
# Combine into a data frame
df = as.data.frame(cbind(opt_m, opt_p))
names(df) <- c("Optimal m", "Optimal p")
# Assign a rowname
if (is.null(rowname) == TRUE){
# Write the row names
rownames(df) <- c("MV CAViaR")
}
else {
rownames(df) <- rowname
}
# Return the loss_vector and the minimzer
return(list(opt_m, loss_vec, df))
}
#' Function that selects the optimal number of lags
#'
#' @param y - response vector
#' @param x - predictor variables
#' @param orig - forecast origin
#' @param end - ending of validation set
#' @param tau - VaR in question
#' @param low_m - low value of m to consider
#' @param high_m - high value of m to consider
#'
#' @return - returns the optimal value of m
#' @export
#'
#' @examples - opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = 757, end = 1007, tau = 0.01, low_m =1, high_m = 5, low_p = 1, high_p = 10, ar_tf = 2, mod_di = 1)
opt_mp = function(y, x, orig, end = NULL, tau, low_m = 1, high_m, low_p = 1, high_p, mod_di = 0, ar_tf = 1, print_mdl = 0, model = 1, print_mp = 0, rowname = NULL){
# Initialize a loss matrix
loss_mat = matrix(0, high_p-low_p + 1,high_m-low_m + 1)
# Initialize a p vector
p_vec = seq(low_p, high_p, by = 1)
# Loop through and populate the loss vector
for (i in 1:nrow(loss_mat)){
loss_mat[i,] = opt_m(y = y, x = x, orig = orig, end = end, tau = tau, low_m = low_m, high_m = high_m, p = i, mod_di = mod_di, ar_tf = ar_tf, print_mdl = print_mdl, model = model)[[2]]
}
# Find the minimizer
opt_p = which(loss_mat == min(loss_mat), arr.ind = TRUE)[1,1]
opt_m = which(loss_mat == min(loss_mat), arr.ind = TRUE)[1,2]
# Print the optimal p and optimal m
df = as.data.frame(cbind(opt_m, opt_p))
names(df) <- c("Optimal m", "Optimal p")
# Assign a rowname
if (is.null(rowname) == TRUE){
if (ar_tf == 1){
# Write the row names
rownames(df) <- c("MV CAViaR + AR")
} else if (ar_tf == 2){
# Write the row names
rownames(df) <- c("MV CAViaR + SAV")
} else if (ar_tf == 3){
# Write the row names
rownames(df) <- c("MV CAViaR + AS")
} else {
rownames(df) <- c("Unknown Model")
}
}
else {
rownames(df) <- rowname
}
# Print the df if the option is turned on
if (print_mp == 1){
print(df)
}
# Return the loss_vector and the minimzer
return(list(opt_m, opt_p, loss_mat, df))
}
#' A function that combines optimal values of m and p into a final table
#'
#' @param m1 - the data frame from the "MV CAViaR" run
#' @param m2 - the data frame from the "MV CAViaR + AR" run
#' @param m3 - the data frame from the "MV CAViaR + SAV" run
#' @param m4 - the data frame from the "MV CAViaR + AS" run
#'
#' @return - a nicely formatted table
#' @export
#'
#' @examples - pretty_pm(opt_pred_nl[[3]], opt_pm_m1[[4]], opt_pm_m2[[4]], opt_pm_m3[[4]])
pretty_pm = function(m1, m2, m3, m4){
# Merge the individual data frames
pm_pretty_df = rbind(m1, m2, m3, m4)
# Format nicely
pm_pretty_df %>% kable(caption = "Optimal Number of Diffusion Indices (m) and Lags (p) for Different Models", digits = 0) %>% kable_styling("striped", full_width = F) %>% kable_styling() %>% footnote(general = "The MV CAViaR model doesn't have an optimal value for p because there are no AR lags in the model"
)
}
#' Here is a function that runs the univariate CAViaR model 4 times
#'
#' @param df - the percent change data frame to consider
#' @param nfcst - number of forecasts to run
#' @param tau - the VaR level to consider
#' @param no_run - specifies if any models should not be run
#'
#' @return - a list of the 4 univariate model forecasts
#' @export
#'
#' @examples - aceg = gen_uv_test(pc_df, 1, 0.05, no_run = c(1,1,0,1))
gen_uv_test = function(df, nfcst, tau, no_run = c(0,0,0,0)){
# model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
# Initialize a list
out_list = list()
# Run the four models - model 1; SAV
if (no_run[1] == 0){
uvcav_1 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 1, G = 10, col = 1, level = tau)
}
# Add a filler if there's no entry
else {
uvcav_1 = 0
}
# Model 2 - AS
if (no_run[2] == 0){
uvcav_2 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 2, G = 10, col = 1, level = tau)
}
else {
uvcav_2 = 0
}
# Model 3 - GARCH
if (no_run[3] == 0){
uvcav_3 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 3, G = 10, col = 1, level = tau)
}
else {
uvcav_3 = 0
}
# Model 4 - Adaptive
if (no_run[4] == 0){
uvcav_4 = rolling_predictions(df[,1], range_data = (1:length(df[,1])), nfcst = nfcst, model = 4, G = 10, col = 1, level = tau)
}
else {
uvcav_4 = 0
}
# Export the data as a list
return(list(uvcav_1, uvcav_2, uvcav_3, uvcav_4))
}
#' Function to plot the data which we generate in previous functions
#'
#' @param plot_matrix - matrix with the data to plot
#' @param norm_value - what to subtact from the data to make it on a percentage change basis. Default is 100.
#'
#' @return
#' @export - a plot of the data by diffusion index number
#'
#' @examples = plt_data(plot_mtx[[1]]), abc = plt_data(plot_mat, tau = 0.01)
plt_data = function(plot_matrix, tau, resp_var, ntest){
# Establish a maximum and minimum value
max_val = max(plot_matrix[,1:ncol(plot_matrix)])
min_val = min(plot_matrix[,1:ncol(plot_matrix)])
# Calculate inital and ending time value
start = index(plot_matrix)[1]
end = index(plot_matrix)[nrow(plot_matrix)]
ind_vals = index(plot_matrix) - start
# Create an initial plot and add lines
for (i in 1:ncol(plot_matrix)){
if (i == 1){
# 4/2/2020 - fixing the index
plot.ts(ind_vals,plot_matrix[,i], type = "l", xlab = paste("Days Since", as.Date(start)), ylab = "Percent Change in PG", ylim = c(min_val,max_val), lwd = 1, main = paste("Predicting", resp_var, "Returns from", as.Date(start), "to", as.Date(end)), sub = paste("The VaR Level is ", 100*tau, "%", "; There are ", ntest, " Trading Days Plotted Above", sep = ""))
# plot.ts(index(plot_matrix), plot_matrix[,i], type = "l", xlab = "Trading Days", ylab = "Percent Change in PG", ylim = c(min_val,max_val), lwd = 1, main = "Predicting PG Returns Over Last 250 Trading Days in 2008", sub = paste("The VaR Level is ", 100*tau, "%", sep = ""))
} else if(i %in% seq(2,8,1)) {
lines(ind_vals,plot_matrix[,i], col = i-1, lty = 2)
} else {
lines(ind_vals,plot_matrix[,i], col = i-1, lty = 2, lwd = 2)
}
}
# Define a sequence for plotting
plot_seq = seq(1, ncol(plot_matrix))
legend("topleft", legend = c(colnames(plot_matrix)), col = plot_seq, lty = c(1, rep(2, 7), rep(3, ifelse(ncol(plot_matrix)-8 <= 0, 0, ncol(plot_matrix)-8))), lwd = c(1, rep(1, 7), rep(2, ifelse(ncol(plot_matrix)-8 <= 0, 0, ncol(plot_matrix)-8))))
# Add a line for 0
# abline(h = 0, col = "black", lty = 2)
}
#' A function to calculate losses based on the test sample
#'
#' @param true_vec - the true vector of returns
#' @param pred_vec - the predicted vector from the model runs
#' @param tau - VaR level. Must match what the model used
#'
#' @return - total losses and the entire loss vector
#' @export
#'
#' @examples
loss_test = function(true_vec, pred_vec, tau){
# Initialize a loss vector
lvec = rep(0, length(true_vec))
# Initialize a break vector to see when VaR is broken
bvec = rep(0, length(true_vec))
for (i in 1:length(true_vec)){
# Calculate an indicator variable
bvec[i] = ifelse(true_vec[i] < pred_vec[i], 1,0)
# Use indicator in function below
lvec[i] = (tau - bvec[i])*(true_vec[i] - pred_vec[i])
}
# Add up the losses
# sumloss = sum(lvec)/length(lvec)
sumloss = sum(lvec)
# Add up the VaR breakage
varbreak = sum(bvec)/length(bvec)
return(list(sumloss,lvec, varbreak, bvec))
}
#' A function to calculate losses based on the plot matrix
#'
#' @param data_mat - a matrix of forecasted VaR values, with the true value in the first column
#' @param tau - VaR level. Must match what the model used
#'
#' @return - a list of four items.
#' 1 = a vector of the losses of all models.
#' 2 = a vector showing the percentage of VaR breaks by model
#' 3 = the loss matrix
#' 4 = the break matrix
#' @export
#'
#' @examples
gen_loss_test = function(data_mat, tau){
# Initialize loss and break matrices
lmat = bmat = matrix(0, nrow = nrow(data_mat), ncol = ncol(data_mat)-1)
# bvec = rep(0, length(true_vec))
# Populate the matrices
for (i in 1:nrow(lmat)){
for (j in 1:(ncol(lmat))){
# Calculate an indicator variable
bmat[i,j] = ifelse(data_mat[i,1] < data_mat[i,j+1], 1,0)
# Use indicator in function below
lmat[i,j] = (tau - bmat[i,j])*(data_mat[i,1] - data_mat[i,j+1])
}
}
# Add up the losses
sumloss = colSums(lmat)
# Add up the VaR breakage
varbreak = colSums(bmat)/nrow(bmat)
return(list(sumloss, varbreak, lmat, bmat))
}
#' A function to make a nice comparison of losses
#'
#' @param data_mat - input data matrix used in the calculation of losses
#' @param loss_list - a list of the losses calculated from the CAViaR function
#' @param tau - the risk level used
#' @param ntest - the number of test points
#'
#' @return
#' @export - returns a nicely formatted table
#'
#' @examples - pretty_tables(plot_mat, l_list, tau = 0.01)
pretty_tables = function(data_mat, loss_list, tau, ntest){
# Combine into a data frame
df = as.data.frame(rbind(loss_list[[1]], loss_list[[2]]))
# Calculate inital and ending time value
start = index(data_mat)[1]
end = index(data_mat)[nrow(data_mat)]
# Add row/column names
colnames(df) <- colnames(data_mat[,-1])
rownames(df) <- c("Losses", "VaR Breaks (%)")
# Convert to a table
df %>% kable(caption = paste("Comparison of VaR Methods for a ", tau*100, "% VaR", sep = ""), digits = 3) %>% kable_styling("striped", full_width = F) %>% kable_styling() %>% footnote(general = paste("Calculated using", ntest, "trading days from", as.Date(start), "to", as.Date(end)))
}
#' A dressed up version of the export function
#'
#' @param var_file - file to export
#' @param path - filepath
#' @param filename - name of the file, ending with .CSV
#'
#' @return
#' @export - exported CSV file
#'
#' @examples - exp_func(var_file = var_1pc_2016_usetf[[1]], path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "TEST.csv")
exp_func = function(var_file, path, filename){
# Write a zoo
write.zoo(var_file, paste0(path, filename), quote = FALSE, sep = ",")
}
# exp_func(var_file = var_1pc_2016_usetf[[1]], path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "TEST.csv")
#' This is the "master" function where we'll evaluate the importance of the VaR model over several time periods
#'
#' @param symbol_list - a list of symbols to feed into the model
#' @param resp_var - the response variable
#' @param compl_case - should the model require complete cases? Default value is 1.
#' @param adj_close - use adjusted close price for the predictors? Default value is 1.
#' @param resp_adj_close - use adjusted close price for the response? Default value is 1.
#' @param start_date - start date to pull data from
#' @param end_date - end date to pull data from
#' @param nval - number of validation points to use
#' @param ntest - number of test points to use
#' @param tau - VaR level to use
#' @param low_m - low number of predictors to test
#' @param high_m - low number of predictors to test
#' @param uv_list - a list of a pre-run univariate model. If a data frame is not provided, the lengthy uv model will run
#' @param no_run - things not to run in the model
#' @param low_p - low value for number of lags
#' @param high_p - high value for number of lags
#' @param na_interp - should the function interpolate NA's
#' @param print_mdl - print the model summaries?
#' @param print_mp - print the optimal values for p and m
#' @param lag_pred - do you want to lag the m predictors (default is 1; strongly recommended)
#' @param rowname - what to name the rows of the nice p and m matrix
#' @param export_csv - do you want to export a CSV? Default is 1.
#' @param path - path to export the CSV
#' @param filename - what to name the CSV
#'
#' @return - a list of the plot matrix, a plot, a list with losses, and a table
#' @export - a plot and a table
#'
#' @examples - cav_simul(c("DIS", "GE", "IBM", "MMM", "XOM"), resp_var = "PG", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 5, tau = 0.01, uv_list = uv_cav_list)
cav_simul = function(symbol_list, resp_var, compl_case = 1, adj_close = 1, resp_adj_close = 1, start_date = "1900-01-01", end_date = Sys.Date(), nval, ntest, tau, low_m = 1, high_m, low_p = 1, high_p, uv_list = NULL, no_run = c(0,0,0,0), na_interp = TRUE, print_mdl = 0, print_mp = 0, lag_pred = 1, rowname = NULL, export_csv = 1, path, filename){
# Select data parameters, pull the data, and percent change the data
df = diff_index_df(symbol_list = symbol_list, resp_var = resp_var, compl_case = compl_case, adj_close = adj_close, resp_adj_close = resp_adj_close, start_date = start_date, end_date = end_date, lag_pred = lag_pred)
# Take the percent change of the data
pc_df = pc_diff_index(df)
# Extract the legnth of the data frame
nr = test_end = nrow(pc_df)
# Calculate the start of the val period, the end of the val period, and the beginning and end of test period
test_orig = test_end - ntest
val_end = test_orig
val_orig = test_orig - nval
# Test for the optimal number of parameters
opt_pred_nl = opt_m(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, rowname = rowname)
opt_pred_art1 = opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, low_p = low_p, high_p = high_p,mod_di = 1, ar_tf = 1, print_mdl = print_mdl, print_mp = print_mp, rowname = rowname)
opt_pred_art2 = opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, low_p = low_p, high_p = high_p,mod_di = 1, ar_tf = 2, print_mdl = print_mdl, print_mp = print_mp, rowname = rowname)
opt_pred_art3 = opt_mp(y = pc_df[,1], x = pc_df[,-1], orig = val_orig, end = val_end, tau = tau, low_m = low_m, high_m = high_m, low_p = low_p, high_p = high_p, mod_di = 1, ar_tf = 3, print_mdl = print_mdl, print_mp = print_mp, rowname = rowname)
# gen_uv_test(pc_df, 1, 0.05, no_run = c(1,1,0,1))
# Use the above forecasts to input into the above
mv_fcst = mod_di(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_nl[[1]], tau = tau, print_mdl = print_mdl)
mv_fcst_art1 = mod_di_wl(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_art1[[1]], p = opt_pred_art1[[2]], tau = tau, ar_tf = 1, print_mdl = print_mdl)
mv_fcst_art2 = mod_di_wl(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_art2[[1]], p = opt_pred_art2[[2]], tau = tau, ar_tf = 2, print_mdl = print_mdl)
mv_fcst_art3 = mod_di_wl(pc_df[,1], pc_df[,-1], orig = test_orig, m = opt_pred_art3[[1]], p = opt_pred_art3[[2]], tau = tau, ar_tf = 3, print_mdl = print_mdl)
# Calculate the number of predictions
if (is.null(uv_list) == TRUE){
# Print a warning
print("WARNING: Not supplying an input data frame will require this function to run for a significant amount of time (1hr+)")
# Call the function
# gen_uv_test = function(df, nfcst, tau, no_run = c(0,0,0,0)){
# print(head(pc_df))
uv_list = gen_uv_test(df = pc_df, nfcst = ntest, tau = tau, no_run = no_run)
# Add to a data frame
# Incorporate the rolling predictions function results here
plot_mat = cbind(pc_df[(test_orig+1):nrow(pc_df),1], mv_fcst$yhat[1:ntest], mv_fcst_art1$yhat[1:ntest], mv_fcst_art2$yhat[1:ntest], mv_fcst_art3$yhat[1:ntest], uv_list[[1]][(test_orig+1):test_end]*(-1), uv_list[[2]][(test_orig+1):test_end]*(-1), uv_list[[3]][(test_orig+1):test_end]*(-1), uv_list[[4]][(test_orig+1):test_end]*(-1))
} else {
# Assign the columns of the data frame
# head(var_5pc_2010_usetf[[1]][,6:9])
# model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
# test_df = head(var_5pc_2010_usetf[[1]][,6:9])
# test_df$SAV
# test_df$`Abs. Slope`
# test_df$`Ind. GARCH`
# test_df$Adaptive
plot_mat = cbind(pc_df[(test_orig+1):nrow(pc_df),1], mv_fcst$yhat[1:ntest], mv_fcst_art1$yhat[1:ntest], mv_fcst_art2$yhat[1:ntest], mv_fcst_art3$yhat[1:ntest], uv_list$SAV, uv_list$`Abs. Slope`, uv_list$`Ind. GARCH`, uv_list$Adaptive)
}
# Count the NAs and print a warning
print(paste("NOTE: There are ", sum(is.na(plot_mat)), " NA(s) in the dataset", sep = ""))
# Linearly interpolate the NAs
if (na_interp == TRUE){
# Assign the plot matrix to a new value
plot_mat_na <- plot_mat
# Print a warning
print("WARNING: There were missing values in the plot matrix.")
# Interpolate the NA's
for (i in 1:ncol(plot_mat_na)){
# Interpolate the data
plot_mat[,i] <- na.approx(plot_mat_na[,i])
}
}
# model type (1 - SAV, 2 - AS, 3 - GARCH, 4 - ADAPTIVE)
# Add descriptive titles onto the plot_mat
colnames(plot_mat) <- c(resp_var, "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")
# colnames(plot_mat) <- c("SPY", "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")
# Plot everything
plot = plt_data(plot_mat, tau = tau, resp_var = resp_var, ntest = ntest)
# Calculate losses
l_list = gen_loss_test(plot_mat, tau = tau)
# Put into tables
tables = pretty_tables(plot_mat, l_list, tau = tau, ntest = ntest)
# Run the function for optimal p and m
pm_table = pretty_pm(opt_pred_nl[[3]], opt_pred_art1[[4]], opt_pred_art2[[4]], opt_pred_art3[[4]])
# Export the matrix
if (export_csv == 1){
exp_func(var_file = plot_mat, path, filename)
}
# Print the tables and the plot
print(plot)
print(tables)
print(pm_table)
return(list(plot_mat, plot, l_list, tables, plot_mat_na, pm_table))
}
#' A function to input the VaR files, plot them and generate tables
#'
#' @param file_path - file path to use
#' @param filename - name of the file
#' @param tau - quantile to use
#' @param resp_var - response variable to use in the plot
#' @param ntest - number of test points
#' @param cn_input - column name inputs
#'
#' @return - a list of the xts file, the plot, the loss list, and tables
#' @export - a plot and tables
#'
#' @examples - test = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2008_us_etf.csv", 0.01)
var_input_disp = function(file_path, filename, tau, resp_var = "SPY", ntest = 250, cn_input = c("SPY", "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")){
# var_input_disp = function(file_path, filename, tau, resp_var = "SPY", ntest = 250, cn_input = c("SPY", "MV CAViaR", "MV CAViaR + AR", "MV CAViaR + SAV", "MV CAViaR + AS", "SAV", "Abs. Slope", "Ind. GARCH", "Adaptive")){
# Import data
plot_mat = read.csv(paste0(file_path,filename), sep = ",", header = T, stringsAsFactors = FALSE)
# Fix date format
plot_mat$Index = as.Date(plot_mat$Index)
# Convert to an xts
plot_mat = xts(plot_mat[,-1], order.by = plot_mat[,1])
# Fix column names
colnames(plot_mat) <- cn_input
# Plot everything
plt_data(plot_mat, tau = tau, resp_var = resp_var, ntest = ntest)
# plot = plt_data(plot_mat, tau = tau, resp_var = resp_var, ntest = ntest)
# Calculate losses
l_list = gen_loss_test(plot_mat, tau = tau)
# Put into tables
df = as.data.frame(rbind(l_list[[1]], l_list[[2]]))
# Calculate inital and ending time value
start = index(plot_mat)[1]
end = index(plot_mat)[nrow(plot_mat)]
# Add row/column names
colnames(df) <- colnames(plot_mat[,-1])
rownames(df) <- c("Losses", "VaR Breaks (%)")
# Convert to a table
print(df, digits = 3)
# print(formattable(df, digits = 3))
# df %>% kable(caption = paste("Comparison of VaR Methods for a ", tau*100, "% VaR", sep = ""), digits = 3) %>% kable_styling("striped", full_width = F) %>% kable_styling() %>% footnote(general = paste("Calculated using", ntest, "trading days from", as.Date(start), "to", as.Date(end)))
# pm_table = pretty_tables(plot_mat, l_list, tau = tau, ntest = ntest)
# Print the tables and the plot
# print(plot)
# print(tables)
# print(pm_table)
# Return the xts, the plot, the loss list, and the tables
return(list(plot_mat))
# return(list(plot_mat, plot, l_list, tables))
}
# return(list(plot_mat, plot, l_list, tables))
# Call the above function
v1_2008_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2008_us_etf.csv", 0.01)
# pretty_tables(v1_2008_usetf[[1]], v1_2008_usetf[[3]], tau = 0.01, ntest = 250)
v5_2008_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2008_us_etf.csv", 0.05)
v10_2008_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2008_us_etf.csv", 0.10)
# head(v10_2008_usetf[[1]])
# v10_2008_usetf
# 1%, 5%, 10% VaR - 2008 - 1st set of predictors
# var_1pc_2008_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2008_us_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2008_us_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2008_us_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2008_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2008_glob_etf.csv", 0.01)
v5_2008_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2008_glob_etf.csv", 0.05)
v10_2008_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2008_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2008 - 2nd set of predictors
# var_1pc_2008_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2008_glob_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2008_glob_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2008_glob_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# 1%, 5%, 10% VaR - 2008 - 3rd set of predictors
# var_1pc_2008_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2008_comm_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2008_comm_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2008_comm_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2008_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2008_bond_etf.csv", 0.01)
v5_2008_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2008_bond_etf.csv", 0.05)
v10_2008_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2008_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2008 - 4th set of predictors
# var_1pc_2008_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2008_bond_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2008_bond_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2008_bond_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2008_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2008_all_etf.csv", 0.01)
v5_2008_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2008_all_etf.csv", 0.05)
v10_2008_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2008_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2008 - 5th set of predictors
# var_1pc_2008_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2008_all_etf.csv", uv_list = var_1pc_2008_usetf[[1]])
# var_5pc_2008_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2008_all_etf.csv", uv_list = var_5pc_2008_usetf[[1]])
# var_10pc_2008_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2004-01-01", end_date = "2008-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2008_all_etf.csv", uv_list = var_10pc_2008_usetf[[1]])
# Call the above function
v1_2010_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2010_us_etf.csv", 0.01)
v5_2010_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2010_us_etf.csv", 0.05)
v10_2010_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2010_us_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2010 - 1st set of predictors
# var_1pc_2010_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2010_us_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2010_us_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2010_us_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2010_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2010_glob_etf.csv", 0.01)
v5_2010_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2010_glob_etf.csv", 0.05)
v10_2010_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2010_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2010 - 2nd set of predictors
# var_1pc_2010_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2010_glob_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2010_glob_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2010_glob_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# 1%, 5%, 10% VaR - 2010 - 3rd set of predictors
# var_1pc_2010_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2010_comm_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2010_comm_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2010_comm_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2010_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2010_bond_etf.csv", 0.01)
v5_2010_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2010_bond_etf.csv", 0.05)
v10_2010_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2010_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2010 - 4th set of predictors
# var_1pc_2010_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2010_bond_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2010_bond_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2010_bond_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2010_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2010_all_etf.csv", 0.01)
v5_2010_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2010_all_etf.csv", 0.05)
v10_2010_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2010_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2010 - 5th set of predictors
# var_1pc_2010_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2010_all_etf.csv", uv_list = var_1pc_2010_usetf[[1]])
# var_5pc_2010_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2010_all_etf.csv", uv_list = var_5pc_2010_usetf[[1]])
# var_10pc_2010_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2006-01-01", end_date = "2010-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2010_all_etf.csv", uv_list = var_10pc_2010_usetf[[1]])
# Call the above function
v1_2014_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2014_us_etf.csv", 0.01)
v5_2014_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2014_us_etf.csv", 0.05)
v10_2014_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2014_us_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2014 - 1st set of predictors
# var_1pc_2014_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2014_us_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2014_us_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2014_us_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2014_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2014_glob_etf.csv", 0.01)
v5_2014_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2014_glob_etf.csv", 0.05)
v10_2014_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2014_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2014 - 2nd set of predictors
# var_1pc_2014_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2014_glob_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2014_glob_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2014_glob_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# 1%, 5%, 10% VaR - 2014 - 3rd set of predictors
# var_1pc_2014_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2014_comm_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2014_comm_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2014_comm_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2014_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2014_bond_etf.csv", 0.01)
v5_2014_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2014_bond_etf.csv", 0.05)
v10_2014_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2014_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2014 - 4th set of predictors
# var_1pc_2014_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2014_bond_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2014_bond_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2014_bond_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2014_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2014_all_etf.csv", 0.01)
v5_2014_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2014_all_etf.csv", 0.05)
v10_2014_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2014_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2014 - 5th set of predictors
# var_1pc_2014_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2014_all_etf.csv", uv_list = var_1pc_2014_usetf[[1]])
# var_5pc_2014_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2014_all_etf.csv", uv_list = var_5pc_2014_usetf[[1]])
# var_10pc_2014_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2010-01-01", end_date = "2014-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2014_all_etf.csv", uv_list = var_10pc_2014_usetf[[1]])
# Call the above function
v1_2016_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_1pc_2016_us_etf.csv", 0.01)
v5_2016_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_5pc_2016_us_etf.csv", 0.05)
v10_2016_usetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/","var_10pc_2016_us_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2016 - 1st set of predictors
# var_1pc_2016_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_1pc_2016_us_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_5pc_2016_us_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_us_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 9, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_US_ETF_runs/", filename = "var_10pc_2016_us_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# Call the above function
v1_2016_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_1pc_2016_glob_etf.csv", 0.01)
v5_2016_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_5pc_2016_glob_etf.csv", 0.05)
v10_2016_globetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/","var_10pc_2016_glob_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2016 - 2nd set of predictors
# var_1pc_2016_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_1pc_2016_glob_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_5pc_2016_glob_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_glob_etf = cav_simul(c("JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 10, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_glob_ETF_runs/", filename = "var_10pc_2016_glob_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# 1%, 5%, 10% VaR - 2016 - 3rd set of predictors
# var_1pc_2016_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_1pc_2016_comm_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_5pc_2016_comm_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_comm_etf = cav_simul(c("DBA", "DBC", "DBE", "DBB"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_comm_ETF_runs/", filename = "var_10pc_2016_comm_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# Call the above function
v1_2016_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_1pc_2016_bond_etf.csv", 0.01)
v5_2016_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_5pc_2016_bond_etf.csv", 0.05)
v10_2016_bondetf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/","var_10pc_2016_bond_etf.csv", 0.10)
# iShares 1-3 Year Treasury Bond Fund (SHY)
# iShares 7-10 Year Treasury Bond Fund (IEF)
# iShares 20+ Year Treasury Bond Fund (TLT)
# iShares iBoxx $ Investment Grade Corporate Bond ETF (LQD)
# 1%, 5%, 10% VaR - 2016 - 4th set of predictors
# var_1pc_2016_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_1pc_2016_bond_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_5pc_2016_bond_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_bond_etf = cav_simul(c("SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 4, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_bond_ETF_runs/", filename = "var_10pc_2016_bond_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
# Call the above function
v1_2016_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_1pc_2016_all_etf.csv", 0.01)
v5_2016_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_5pc_2016_all_etf.csv", 0.05)
v10_2016_alletf = var_input_disp("/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/","var_10pc_2016_all_etf.csv", 0.10)
# 1%, 5%, 10% VaR - 2016 - 5th set of predictors
# var_1pc_2016_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10, tau = 0.01, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_1pc_2016_all_etf.csv", uv_list = var_1pc_2016_usetf[[1]])
# var_5pc_2016_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.05, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_5pc_2016_all_etf.csv", uv_list = var_5pc_2016_usetf[[1]])
# var_10pc_2016_all_etf = cav_simul(c("XLU", "XLP", "XLV", "XLK", "XLY", "XLI", "XLF", "XLB", "XLE", "JXI", "KXI", "IXJ", "IXP", "IXN", "RXI", "EXI", "IXG", "MXI", "IXC", "SHY", "IEF", "TLT", "LQD"), resp_var = "SPY", start_date = "2012-01-01", end_date = "2016-12-31", nval = 250, ntest = 250, low_m = 1, high_m = 23, low_p = 1, high_p = 10,tau = 0.10, print_mdl = 1, print_mp = 1, path = "/Users/stevenmoen/Documents/GitHub/CAViaR_MS_thesis/Data_Export/SPY_all_ETF_runs/", filename = "var_10pc_2016_all_etf.csv", uv_list = var_10pc_2016_usetf[[1]])
LS0tCnRpdGxlOiAiTXVsdGl2YXJpYXRlIENBVmlhUiIKc3VidGl0bGU6ICJBbiBJbnNpZ2h0ZnVsIEFwcHJvYWNoIHRvIFJpc2sgTW9kZWxpbmciCmF1dGhvcjogIlN0ZXZlbiBNb2VuIgpkYXRlOiAiU3VuZGF5LCBNYXkgM3JkLCAyMDIwIgpvdXRwdXQ6CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAotLS0KCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTgsIGZpZy5wYXRoPSdGaWdzLycsCiAgICAgICAgICAgICAgICAgICAgICBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBjYWNoZSA9IFRSVUUpCmBgYAoKIyBBYnN0cmFjdAoKVGhpcyB0aGVzaXMgYnVpbGRzIHVwb24gcHJldmlvdXMgbGl0ZXJhdHVyZSBmb3IgbW9kZWxpbmcgdmFsdWUtYXQtcmlzayAoZGVmaW5lZCBhcyBhbiB4JSBxdWFudGlsZSBvZiBhbiBhc3NldCdzIGRhaWx5IHJldHVybnMpIHVzaW5nIG5vbi1saW5lYXIgQVJNQSB0ZXJtcyBieSBhZGRpbmcgRVRGcyBhcyBleHBsYW5hdG9yeSB2YXJpYWJsZXMgdGhhdCBhcmUgY29tYmluZWQgaW50byBwcmluY2lwYWwgY29tcG9uZW50IHZlY3RvcnMgYXQgdGhlIGZvcmVjYXN0IG9yaWdpbi4gQ29tYmluaW5nIHRoZXNlIHByaW5jaXBhbCBjb21wb25lbnQgdmVjdG9ycyB3aXRoIHRyYW5zZm9ybWF0aW9ucyBvZiBsYWdnZWQgYXV0b3JlZ3Jlc3NpdmUgcmVzcG9uc2UgdmFyaWFibGVzIHJlc3VsdHMgaW4gYSBtb2RlbCB0aGF0IHByb2R1Y2VzIHNpbWlsYXIgcHJlZGljdGl2ZSBhY2N1cmFjeSBkdXJpbmcgcGVyaW9kcyBvZiByZWxhdGl2ZWx5IGxvdyB2b2xhdGlsaXR5IGFsb25nIHdpdGggbW9yZSBpbnNpZ2h0IGludG8gdGhlIGRyaXZlcnMgb2YgdGhlIGNoYW5nZXMgaW4gdGhlIHJlc3BvbnNlIHZhcmlhYmxlLiBJbiBmYWN0LCBvbmUgaW5zaWdodCBnYWluZWQgZnJvbSB0aGUgbmV3IG1vZGVsIGlzIGEgbWV0aG9kIG9mIGRldGVjdGluZyBjaGFuZ2Vwb2ludHMgaW4gdGhlIGVjb25vbXkgYnkgbWVhc3VyaW5nIHRoZSBhbmdsZSBiZXR3ZWVuIHJlc3VsdGFudCB2ZWN0b3JzIGNhbGN1bGF0ZWQgZnJvbSB0aGUgY29tYmluYXRpb24gb2YgcHJpbmNpcGFsIGNvbXBvbmVudCB2ZWN0b3JzIGR1cmluZyBkaWZmZXJlbnQgdGltZSBwZXJpb2RzLiBUaGlzIG1ldGhvZCwgYWxvbmcgd2l0aCBhbmFseXNpcyBvZiB0aGUgc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlIG9mIHRoZSBsYWdnZWQgRVRGcywgYWxsb3dzIGZvciBpbnNpZ2h0IGludG8gY2hhbmdlcyBpbiB0aGUgdW5kZXJseWluZyBlY29ub215LgoKIyBCYWNrZ3JvdW5kIGFuZCBJbnRyb2R1Y3Rpb24KCldoZW4gbW9kZWxpbmcgZmluYW5jaWFsIHRpbWUgc2VyaWVzLCBzaW1wbHkgY29uc2lkZXJpbmcgdGhlIG1lYW4gYW5kIHRoZSB2YXJpYW5jZSBpcyBpbnN1ZmZpY2llbnQuIEluIGZhY3QsIG1vZGVsaW5nIGEgMSUgb3IgYSA1JSBxdWFudGlsZSBvZiBkYWlseSByZXR1cm5zIGlzIGEgd2F5IHRvIHVuZGVyc3RhbmQgd2hhdCBoYXBwZW5zIG9uIHRoZSB3b3JzdCBkYXlzIGFuZCB0byBoYXZlIGEgY2xlYXJlciBwaWN0dXJlIG9mIHdoYXQgbWlnaHQgaGFwcGVuIGR1cmluZyBhIGRvd250dXJuLiBJbmRlZWQsIGZpbmFuY2UgdGhlb3J5IHN1Z2dlc3RzIHRoYXQgYSBwcmltYXJ5IHJlYXNvbiB3aHkgdGhlIFMmUDUwMCwgd2hpY2ggaXMgYSBtYXJrZXQtY2FwaXRhbGl6YXRpb24gd2VpZ2h0ZWQgaW5kZXggY29tcG9zZWQgb2YgdGhlIDUwMC1sYXJnZXN0IHB1YmxpY2x5IHRyYWRlZCBjb21wYW5pZXMgaW4gdGhlIFVuaXRlZCBTdGF0ZXMsIGhhcyBlYXJuZWQgNi44JSBpbmZsYXRpb24tYWRqdXN0ZWQgcHJlLXRheCByZXR1cm4gd2l0aCBkaXZpZGVuZCByZWludmVzdG1lbnQgZnJvbSBKYW51YXJ5IDE4NzEgdGhyb3VnaCBBcHJpbCAyMDIwIChDSVRFKSBpcyBiZWNhdXNlIG9mIHRoZSByaXNrIG9mIGEgc2lnbmlmaWNhbnQgZG93bnR1cm4uIEtlcnJ5IFBlY2h0ZXIgYXQgRm9yYmVzIGRlc2NyaWJlcyBpdCBhcyBhIHByZW1pdW0gZm9yIHRoZSBmYWN0IHRoYXQgInN0b2NrcyBhcmUgcmlza2llciIgYW5kICJtb3JlIHByb25lIHRvIHByaWNlIGZsdWN0dWF0aW9ucyBpbiB0aGUgc2hvcnQgcnVuIiBjb21wYXJlZCB0byBsb3dlciByaXNrIGludmVzdG1lbnRzLiBXaGlsZSB0aGUgbG9uZy1ydW4gcGljdHVyZSBvZiBzdG9jayByZXR1cm5zIGlzIGEgYml0IGNsZWFyZXIsIHRoZSBzaG9ydC1ydW4gaXMgYSBodWdlIHF1ZXN0aW9uIC0gYW4gaW52ZXN0bWVudCBtYW5hZ2VyIHVzaW5nIGZpbmFuY2lhbCBsZXZlcmFnZSB0byBtYWduaWZ5IHJldHVybnMgKHBvc2l0aXZlIG9yIG5lZ2F0aXZlKSB0aGF0IGNvdWxkIGxlYXZlIHRoZW0gaW4gZGlyZSBzdHJhaXRzIGlmIHRoZWlyIGludmVzdG1lbnRzIGZlbGwgcmFwaWRseSwgZGVzcGl0ZSBhIHNvdW5kIGxvbmctcnVuIHN0cmF0ZWd5LgoKV2hpbGUgdGhlcmUgYXJlIG90aGVyIHdheXMgdG8gdW5kZXJzdGFuZCBhbmQgbWVhc3VyZSBkb3duc2lkZSByaXNrLCBhIGNvbW1vbmx5IGFjY2VwdGVkIG1lYW5zIGlzIHVzaW5nIHZhbHVlLWF0LXJpc2sgKFZhUikuIFRoZSBtZXRyaWMgaXMgdW5kZXJzdG9vZCBhcyBmb2xsb3dzOiBhIG9uZS1kYXkgMSUgVmFSIG9mIC0xIG1pbGxpb24gZG9sbGFycyBmb3IgYSBwb3J0Zm9saW8gbWVhbnMgdGhhdCB0aGUgcG9ydGZvbGlvIHdpbGwgbG9zZSBhdCBsZWFzdCAkMSBtaWxsaW9uIG9uIHRoZSAxJSB3b3JzdCB0cmFkaW5nIGRheXMuIEEgbWFqb3IgYWR2YW50YWdlIG9mIFZhUiBpcyB0aGF0IGl0IGRpc3RpbGxzIGEgZGlzdHJpYnV0aW9uIG9mIHJldHVybnMgaW50byBvbmUgbnVtYmVyLiBBcyBzdWNoLCBWYVIgaXMgb2Z0ZW4gdXNlZCBpbiBzdHJlc3MgdGVzdGluZyBieSByZWd1bGF0b3J5IGFnZW5jaWVzIGluIHRoZSBVbml0ZWQgU3RhdGVzLCB0aGUgVW5pdGVkIEtpbmdkb20sIGFuZCBFdXJvcGUgKENJVEUpLgoKTWFueSBvZiB0aGUgYXBwcm9hY2hlcyBmb3IgbW9kZWxpbmcgVmFSIHJlbHkgb24gYSBzZW1pcGFyYW1ldHJpYyBvciBhIG5vbnBhcmFtZXRyaWMgaGlzdG9yaWNhbCBzaW11bGF0aW9uIChBREQgQ0lUQVRJT04gLSBCT1VET1VLSCkuIEFjY29yZGluZyB0byBSb2JlcnQgRW5nbGUgYW5kIFNpbW9uZSBNYW5nYW5lbGxpIGluIGEgMjAwNCBwYXBlciwgdGhlc2UgbWV0aG9kcyBhcmUgdXN1YWxseSBjaG9zZW4gZm9yIOKAnGVtcGlyaWNhbCBqdXN0aWZpY2F0aW9ucyByYXRoZXIgdGhhbiBvbiBzb3VuZCBzdGF0aXN0aWNhbCB0aGVvcnnigJ0gKEFERCBDSVRBVElPTiAtIEVOR0xFKS4gQXMgc3VjaCwgdGhleSBwcm9wb3NlIGEgZnJhbWV3b3JrIGNhbGxlZCBDQVZpYVIgdGhhdCBmb3JlY2FzdHMgdGhlIFZhUiBxdWFudGlsZSBkaXJlY3RseSB1c2luZyBhIGNvbmRpdGlvbmFsIGF1dG9yZWdyZXNzaXZlIHF1YW50aWxlIHNwZWNpZmljYXRpb24uIFRoaXMgYXBwcm9hY2ggYnVpbGRzIHVwb24gdGhlIHN0YXRpc3RpY2FsIGxpdGVyYXR1cmUgdGhhdCBleHRlbmRzIGxpbmVhciBxdWFudGlsZSBtb2RlbHMgdG8gc2V0dGluZ3MgYW1lbmFibGUgdG8gZmluYW5jaWFsIG1vZGVsaW5nLCBzdWNoIGFzIHdpdGggaGV0ZXJvc2tlZGFzdGljIGFuZCBub25zdGF0aW9uYXJ5IGVycm9yIGRpc3RyaWJ1dGlvbnMgKEFERCBDSVRBVElPTiAtIEtPRU5LRVIsIFBPUlROT1kpLgoKCiMgTWV0aG9kcyBVc2VkCgpBIGNvbW1vbiBwcm9ibGVtIGluIHN0YXRpc3RpY2FsIGFuYWx5c2lzIG9jY3VycyB3aGVuIGEgdHJhaW5pbmcgc2FtcGxlIGlzIHNpZ25pZmljYW50bHkgZGlmZmVyZW50IHRoYW4gdGhhdCBvZiB0aGUgdGVzdCBzYW1wbGUuIEluaXRpYWwgbW90aXZhdGlvbnMgZm9yIHRoaXMgcGFwZXIgaW52b2x2ZWQgYW5hbHl6aW5nIHR3byBzdG9ja3MgLSBBbWF6b24gKHRpY2tlcjogQU1aTikgYW5kIFByb2N0b3IgJiBHYW1ibGUgKHRpY2tlcjogUEcpIGFuZCB0aGVpciBwZXJmb3JtYW5jZSBkdXJpbmcgdGhlIGdyZWF0IHJlY2Vzc2lvbi4gQSByZWxldmFudCBxdWVzdGlvbiBvZiBhIGZpbmFuY2lhbCBpbnN0aXR1dGlvbiB3b3VsZCB1bmRlcnN0YW5kYWJseSBiZSBob3cgdGhlaXIgcmlzayBtb2RlbCBwZXJmb3JtZWQgZHVyaW5nIDIwMDgsIGEgaGlnaGx5IHZvbGF0aWxlIHBlcmlvZCB3aGljaCB3YXMgZHJpdmVuIGJ5IHRoZSAid29yc3QgZmluYW5jaWFsIGNyaXNpcyBzaW5jZSB0aGUgR3JlYXQgRGVwcmVzc2lvbiIgYWNjb3JkaW5nIHRvIEdhcnkgQmVja2VyIChDSVRFKSwgYSBOb2JlbC1wcml6ZSB3aW5uaW5nIEVjb25vbWlzdC4gSW50ZXJlc3RpbmdseSwgdGhlIGZvcmVjYXN0IGZvciBBbWF6b24gd2FzIGZhaXJseSBhY2N1cmF0ZSB3aGVyZWFzIHRoZSBmb3JlY2FzdCBmb3IgUEcgd2FzIG5vdC4gT25lIHJlYXNvbiBmb3IgdGhpcyBjb3VsZCBiZSB0aGUgZmFjdCB0aGF0IGEgc3RvY2sgbGlrZSBBbWF6b24gd2FzIGhpZ2hseSB2b2xhdGlsZSBkdXJpbmcgdGhlIHRyYWluaW5nIHNhbXBsZSwgd2hpY2ggaW5jbHVkZWQgZGF0YSBmcm9tIHByZXZpb3VzIHllYXJzIChIT1cgTUFOWT8pLCBidXQgUEcgd2FzIGZhaXJseSBjYWxtLiBIb3cgd291bGQgaXQgYmUgcG9zc2libGUgZm9yIGEgdW5pdmFyaWF0ZSBtb2RlbCBzdWNoIGFzIENBVmlhUiwgdGhhdCBkb2VzIG5vdCBleHBsaWN0bHkgYWNjb3VudCBmb3Igb3RoZXIgZmFjdG9ycywgdG8gZm9yZWNhc3Qgd2VsbD8gV2hhdCBpZiBhIHZvbGF0aWxlIHN0b2NrIHN1Y2ggYXMgQU1aTiB3YXMgaW5jbHVkZWQgaW50byB0aGUgZm9yZWNhc3QgZm9yIFBHIC0gd291bGQgaXQgaW1wcm92ZSB0aGUgZm9yZWNhc3Q/CgpUaHVzLCB0aGUgaWRlYSBvZiBjb21iaW5pbmcgc3RvY2tzIGludG8gYSBtdWx0aXZhcmlhdGUgc2V0dGluZyB0byBjYXB0dXJlIGNvcnJlbGF0aW9ucyBhbmQgYmV0dGVyIGZvcmVjYXN0IHJpc2sgd2FzIGZvcm1lZC4gQSBuYXR1cmFsIGNob2ljZSBhcHBlYXJlZCB0byBiZSB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsLCBvcmlnaW5hbGx5IGRldmVsb3BlZCBieSBTdG9jayBhbmQgV2F0c29uIGZvciBwcmVkaWN0aW5nIGNvbmRpdGlvbmFsIG1lYW5zIFtUV08gQ0lUQVRJT05TXS4gVGhlIG1vZGVsIGZvciBmb3JlY2FzdGluZyB0aGUgY29uZGl0aW9uYWwgbWVhbiBpcyBzcGVjaWZpZWQgYmVsb3cuCgojIyBEaWZmdXNpb24gSW5kZXggTW9kZWwKCkEgdXNlZnVsIG1lYW5zIG9mIHByZWRpY3Rpbmcgc3RvY2sgbW92ZW1lbnRzIGluIHRoZSBmdXR1cmUgaXMgdGhlIFN0b2NrIGFuZCBXYXRzb24gZGlmZnVzaW9uIGluZGV4LiBUaGUgbW9kZWwgaXMgb3V0bGluZWQgYmVsb3csIHdoaWNoIGlzIGFkYXB0ZWQgZnJvbSBNdWx0aXZhcmlhdGUgVGltZSBTZXJpZXMgQW5hbHlzaXMgV2l0aCBSIGFuZCBGaW5hbmNpYWwgQXBwbGljYXRpb25zIGJ5IFJ1ZXkgUy4gVHNheSBbQUREIENJVEFUSU9OXS4KClRoZXJlIGFyZSB0d28gcmVsZXZhbnQgZXF1YXRpb25zOgoKJCQKXGJvbGRzeW1ib2x7el90fSA9IFxib2xkc3ltYm9se0xmX3R9ICsgXGJvbGRzeW1ib2x7XGVwc2lsb25fdH0KJCQKCmFuZCAKCiQkCnlfe3QraH0gPSBcYm9sZHN5bWJvbHtcYmV0YV5ccHJpbWUgZl90fSArIFxib2xkc3ltYm9se2Vfe3QraH19CiQkCgpJbiB0aGUgZmlyc3QgZXF1YXRpb24gJFxib2xkc3ltYm9se3pfdH0gPSAoel97MXR9LCAuLi4uLCB6X3trdH0pXlxwcmltZSQgaXMgYW4gb2JzZXJ2ZWQgdGltZSBzZXJpZXMgd2l0aCBtZWFuIDAsICRcYm9sZHN5bWJvbHtmX3R9JCBpcyBhbiBtLWRpbWVuc2lvbmFsIHZlY3RvciBvZiBjb21tb24gZmFjdG9ycyB3aXRoIG1lYW4gMCBhbmQgaWRlbnRpdHkgY292YXJpYW5jZSBtYXRyaXgsICRcYm9sZHN5bWJvbHtMfSQgaXMgYSAkayQgeCAkbSQgbG9hZGluZyBtYXRyaXgsIGFuZCAkXGJvbGRzeW1ib2x7XGVwc2lsb25fdH0kIGlzIGEgaS5pLmQuIHNlcXVlbmNlIG9mIHJhbmRvbSB2ZWN0b3JzIHdpdGggbWVhbiAwIGFuZCBjb3ZhcmlhbmNlIG1hdHJpeCAkXGJvbGRzeW1ib2x7XFNpZ21hX2V9JC4KCkluIHRoZSBzZWNvbmQgZXF1YXRpb24sIHdoaWNoIHJlcHJlc2VudHMgdGhlIGgtc3RlcCBhaGVhZCBwcmVkaWN0aW9uIGJhc2VkIG9uICRcYm9sZHN5bWJvbHtmX3R9JCwgJHlfdCQgaXMgdGhlIHNjYWxhciB0aW1lIHNlcmllcyBvZiBpbnRlcmVzdCwgJGgkIGlzIHRoZSBmb3JlY2FzdCBob3Jpem9uLCAkXGJvbGRzeW1ib2x7XGJldGF9JCByZXByZXNlbnRzIHRoZSB2ZWN0b3Igb2YgY29lZmZpY2llbnRzLCBhbmQgJGVfdCQgaXMgYSBzZXF1ZW5jZSBvZiB1bmNvcnJlbGF0ZWQgcmFuZG9tIHZhcmlhYmxlcyB3aXRoIG1lYW4gMCBhbmQgY29uc3RhbnQgdmFyaWFuY2UuIAoKVG8gbW9kZWwgdGhlIGRhdGEsIHByaW5jaXBhbCBjb21wb25lbnQgYW5hbHlzaXMgaXMgcGVyZm9ybWVkIG9uIHRoZSBjb3ZhcmlhdGVzIGRlc2NyaWJlZCBiZWxvdyB0byBvYnRhaW4gYW4gZXN0aW1hdGUgb2YgJFxib2xkc3ltYm9se2ZfdH0kLiBUaGVuIHRoZSAkXGJvbGRzeW1ib2x7XGJldGF9JCBjb2VmZmljaWVudHMgYXJlIGVzdGltYXRlZCB1c2luZyBvcmRpbmFyeSBsZWFzdCBzcXVhcmVzLgoKIyMgVW5pdmFyaWF0ZSBDQVZpYVIgTW9kZWwKCkhvd2V2ZXIsIHdvcmsgbmVlZGVkIHRvIGJlIGRvbmUgdG8gYWxpZ24gdGhlIGRpZmZ1c2lvbiBpbmRleCBtb2RlbCB3aXRoIHRoZSBDQVZpYVIgbW9kZWwsIHdoaWNoIGlzIGRlZmluZWQgYmVsb3cuIFRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIGFyZSByZXF1aXJlZCBmb3IgdXNlIGluIHRoZSBDQVZpYVIgbW9kZWw6CgpbREVTQ1JJUFRJT04gT0YgVkFSSUFCTEVTXQoKIyMjIEFkYXB0aXZlIENBVmlhUiBNb2RlbAoKJCQKZl90KFxiZXRhXzEpID0gZl97dC0xfShcYmV0YV8xKSArIFxiZXRhXzFcbGVmdFtcbGVmdCgxKyBcZXhwKEdbeV97dC0xfSAtIGZfe3QtMX0oXGJldGFfMSldKSAgXHJpZ2h0KV57LTF9IC0gXHRoZXRhIFxyaWdodF0gCiQkCgojIyMgU3ltbWV0cmljIEFic29sdXRlIFZhbHVlIENBVmlhUiBNb2RlbAoKJCQKZl90KFxib2xkc3ltYm9se1xiZXRhfSkgPSBcYmV0YV8xICsgXGJldGFfMmZfe3QtMX0oXGJvbGRzeW1ib2x7XGJldGF9KSArIFxiZXRhXzN8eV97dC0xfXwKJCQKCiMjIyBBc3ltbWV0cmljIFNsb3BlIENBVmlhUiBNb2RlbAoKJCQKZl90KFxib2xkc3ltYm9se1xiZXRhfSkgPSBcYmV0YV8xICsgXGJldGFfMmZfe3QtMX0oXGJvbGRzeW1ib2x7XGJldGF9KSArIFxiZXRhXzMoeV97dC0xfSleKyArIFxiZXRhXzQoeV97dC0xfSleLQokJAoKIyMjIEluZGlyZWN0IEdBUkNIICgxLDEpIENBVmlhUiBNb2RlbAoKJCQKZl90KFxib2xkc3ltYm9se1xiZXRhfSkgPSAoXGJldGFfMSArIFxiZXRhXzJmX3t0LTF9XjIoXGJvbGRzeW1ib2x7XGJldGF9KSArIFxiZXRhXzN5X3t0LTF9XjIpXnsxLzJ9CiQkCgojIyBNdWx0aXZhcmlhdGUgQ0FWaWFSIE1vZGVsCgpUaGUgbXVsdGl2YXJpYXRlIENBVmlhUiBtb2RlbCB0YWtlcyBpbnNwaXJhdGlvbiBmcm9tIHRoZSBtb2RlbHMgZGVzY3JpYmVkIGFib3ZlIGluIHNldmVyYWwgc3BlY2lmaWNhdGlvbnMuIFRoZSBnZW5lcmFsIG1vZGVsIGZvcm0gbG9va3MgbGlrZSB0aGUgc3BlY2lmaWNhdGlvbiBiZWxvdy4KClZBUiA9IElOVEVSQ0VQVCArIFBBU1QgVkFMVUVTICsgQVIgQ09NUE9ORU5UICsgRVJST1IKCgojIyMgTXVsdGl2YXJpYXRlIENBVmlhUjogTm8gTGFncyBNb2RlbAoKVkFSID0gSU5URVJDRVBUICsgUEFTVCBWQUxVRVMgKyBFUlJPUgoKIyMjIE11bHRpdmFyaWF0ZSBDQVZpYVIgd2l0aCBBdXRvcmVncmVzc2l2ZSBUZXJtcyBBZGRlZAoKVkFSID0gSU5URVJDRVBUICsgUEFTVCBWQUxVRVMgKyBBUiBDT01QT05FTlQgKyBFUlJPUgoKIyMjIE11bHRpdmFyaWF0ZSBDQVZpYVIgd2l0aCBTeW1tZXRyaWMgQWJzb2x1dGUgVmFsdWUgQXV0b3JlZ3Jlc3NpdmUgVGVybXMgQWRkZWQKClZBUiA9IElOVEVSQ0VQVCArIFBBU1QgVkFMVUVTICsgU0FWIEFSIENPTVBPTkVOVCArIEVSUk9SCgojIyMgTXVsdGl2YXJpYXRlIENBVmlhUiB3aXRoIEFzeW1tZXRyaWMgU2xvcGUgQXV0b3JlZ3Jlc3NpdmUgVGVybXMgQWRkZWQKClZBUiA9IElOVEVSQ0VQVCArIFBBU1QgVkFMVUVTICsgQVMgQVIgQ09NUE9ORU5UICsgRVJST1IKCgojIyBGaXR0aW5nIHRoZSBNb2RlbHMKClRvIGZpdCB0aGUgbW9kZWxzLCBhbiBvcHRpbWFsIHZhbHVlIG9mICRtJCBkaWZmdXNpb24gaW5kaWNlcyBhbmQgJHAkIGF1dG9ncmVzc2l2ZSB0ZXJtcyBhcmUgYWRkZWQgKG9yICQycCQgaW4gdGhlIGNhc2Ugb2YgdGhlIGFzeW1tZXRyaWMgc2xvcGUgbW9kZWwpLiBUaGUgb3B0aW1hbCB2YWx1ZXMgb2YgdGhlc2UgcGFyYW1ldGVycyBhcmUgYXJyaXZlZCBhdCB1c2luZyBhIHZhbGlkYXRpb24gZGF0YXNldC4gSW4gYWxsIG9mIHRoZSBydW5zIGJlbG93LCB0aGVyZSBhcmUgYSB0b3RhbCBvZiA1IHllYXJzIG9mIHRyYWRpbmcgZGF5cywgb3IgYWJvdXQgMSwyNjAgZGF5cyBhc3N1bWluZyAyNTIgdHJhZGluZyBkYXlzIGEgeWVhci4gVGhlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzIGFyZSBsb2dnZWQgYW5kIGRpZmZlcmVuY2VkLCBzaG9ydGVuaW5nIHRoZSBkYXRhc2V0IGJ5IG9uZS4gQWZ0ZXIgZG9pbmcgdGhpcywgdGhlIGxhc3QgMjUwIGRhdGFwb2ludHMgYXJlIHJlc2VydmVkIGFzIHRlc3QgZGF0YSwgYW5kIHRoZSAyNTAgZGF0YXBvaW50cyBiZWZvcmUgdGhhdCBhcmUgdXNlZCBhcyBhIHZhbGlkYXRpb24gc2V0LiBNZWFzdXJlZCBieSB0aGUgbG9zcyBmdW5jdGlvbiB3cml0dGVuIG91dCBiZWxvdywgdGhlIHZhbHVlcyBvZiAkcCQgYW5kICRtJCB0aGF0IG1pbmltaXplIGxvc3NlcyBhcmUgY2hvc2VuIGFuZCB0aGUgb3B0aW1hbCBtb2RlbCBpcyByZWZpdCBvdmVyIGJvdGggdGhlIHRyYWluaW5nIGFuZCB0aGUgdmFsaWRhdGlvbiBkYXRhIGNvbWJpbmVkIGFuZCB0aGVuIGV2YWx1YXRlZCBvbiB0aGUgdGVzdCBkYXRhLiBOb3RlIHRoYXQgdGhpcyBhbiBvcHRpbWFsIG1vZGVsIGlzIGNob3NlbiBmb3IgZWFjaCBvZiB0aGUgZm91ciBtdWx0aXZhcmlhdGUgQ0FWaWFSIHNwZWNpZmljYXRpb25zIGRlc2NyaWJlZCBhYm92ZSwgc28gdGhlcmUgYXJlIDQgb3B0aW1hbCBzZXRzIG9mICRwJCBhbmQgJG0kIGNob3NlbiBmb3IgZWFjaCBzZXQgb2YgbW9kZWwuIFRodXMsIHRoZXJlIGFyZSA4IG1vZGVscyBjb21wYXJlZCBvbiB0aGUgdGVzdCBkYXRhIC0gNCB1bml2YXJpYXRlIENBVmlhUiBtb2RlbHMgYW5kIDQgbXVsdGl2YXJpYXRlIENBVmlhUiBtb2RlbHMuCgpbTE9TUyBGVU5DVElPTl0KCiMgRGF0YSBVc2VkCgpUaGUgcmVzcG9uc2UgdmFyaWFibGUgdXNlZCBpbiB0aGlzIGFuYWx5c2lzIGlzIFNQWSwgd2hpY2ggaXMgYW4gZXhjaGFuZ2UtdHJhZGVkIGZ1bmQgdGhhdCBhaW1zIHRvIHRyYWNrIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGUgUyZQIDUwMCwgd2hpY2ggaXMgZGlzY3Vzc2VkIGFib3ZlLiBJdCBpcyBicm9hZGx5IHVzZWQgYXMgYSBiZWxsd2VhdGhlciBvZiB0aGUgVS5TLiBlY29ub215IChDSVRFKSwgYW5kIGhhcyB0aGUgYWR2YW50YWdlIG9mIGF2b2lkaW5nIHN1cnZpdm9yc2hpcCBiaWFzIC0gd2hpbGUgYW4gaW5kaXZpZHVhbCBzdG9jayBtaWdodCBnbyBiYW5rcnVwdCBvciBtZXJnZSB3aXRoIGFub3RoZXIsIGl0J3MgcmVhc29uYWJsZSB0byBhc3N1bWUgdGhhdCB0aGVzZSBpc3N1ZXMgZG8gbm90IGFwcGx5IHdpdGggYW4gRVRGLiAKCkZvbGxvd2luZyB0aGlzIGxvZ2ljLCB0aGVyZSBhcmUgc2V2ZXJhbCBjbGFzc2VzIG9mIHJlc3BvbnNlIHZhcmlhYmxlcyB1c2VkIGluIHRoaXMgYW5hbHlzaXMuIFRoZSBmaXJzdCBncm91cCBpcyBhIHNldCBvZiBVLlMuIHNlY3RvciBFVEZzIG9idGFpbmVkIGZyb20gU2Vla2luZyBBbHBoYSB1c2luZyB0aGUgbGluayBiZWxvdy4gQXMgd2l0aCB0aGUgcmVzcG9uc2UgdmFyaWFibGUsIHRoZXNlIEVURnMgd2VyZSBwdWJsaWNseSB0cmFkZWQgdGhyb3VnaG91dCB0aGUgR3JlYXQgUmVjZXNzc2lvbi4KCmh0dHBzOi8vc2Vla2luZ2FscGhhLmNvbS9ldGZzLWFuZC1mdW5kcy9ldGYtdGFibGVzL3NlY3RvcnMKCmEuIFV0aWxpdGllcyAoWExVKQpiLiBDb25zdW1lciBTdGFwbGVzIChYTFApCmMuIEhlYWx0aGNhcmUgKFhMVikKZC4gVGVjaG5vbG9neSAoWExLKQplLiBDb25zdW1lciBEaXNjcmV0aW9uYXJ5IChYTFkpCmYuIEluZHVzdHJpYWwgKFhMSSkKZy4gRmluYW5jaWFsIFNlcnZpY2VzIChYTEYpCmguIEJhc2ljIE1hdGVyaWFscyAoWExCKQppLiBFbmVyZ3kgKFhMRSkKClRoZSBzZWNvbmQgaXMgR2xvYmFsIFNlY3RvciBFVEZzLCBhbHNvIG9idGFpbmVkIGZyb20gU2Vla2luZyBBbHBoYS4gVGhlIHJhdGlvbmFsZSBmb3IgaW5jbHVkaW5nIHRoZXNlIGlzIHRoYXQgcGVyaGFwcyBzb21lIGdsb2JhbCBleHBvc3VyZSBpcyB1c2VmdWwgaW4gdW5kZXJzdGFuZGluZyB0aGUgYnJvYWRlciBtYXJrZXQuCgphLiBVdGlsaXRpZXMgKEpYSSkKYi4gQ29uc3VtZXIgU3RhcGxlcyAoS1hJKQpjLiBIZWFsdGhjYXJlIChJWEopCmQuIFRlbGVjb21tdW5pY2F0aW9ucyAoSVhQKQplLiBUZWNobm9sb2d5IChJWE4pCmYuIENvbnN1bWVyIERpc2NyZXRpb25hcnkgKFJYSSkKZy4gSW5kdXN0cmlhbCAoRVhJKQpoLiBGaW5hbmNpYWwgU2VydmljZXMgKElYRykKaS4gQmFzaWMgTWF0ZXJpYWxzIChNWEkpCmouIEVuZXJneSAoSVhDKQoKVGhlIHRoaXJkIGlzIGJvbmQgRVRGcywgYWxzbyBvYnRhaW5lZCBmcm9tIFtDSVRFXS4gTGlrZSB0aGUgcHJldmlvdXMgdHdvLCB0aGVzZSBFVEZzIHBvdGVudGlhbGx5IGNvbnRhaW4gZm9yd2FyZC1sb29raW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBzdG9jayBtYXJrZXQuIExpbmsgYmVsb3c6CgphLiBpU2hhcmVzIDEtMyBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoU0hZKQpiLiBpU2hhcmVzIDctMTAgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKElFRikKYy4gaVNoYXJlcyAyMCsgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFRMVCkKZC4gaVNoYXJlcyBpQm94eCAkIEludmVzdG1lbnQgR3JhZGUgQ29ycG9yYXRlIEJvbmQgRVRGIChMUUQpCgpMYXN0bHksIGFsbCBvZiB0aGUgYWJvdmUgYXJlIHJ1biB0b2dldGhlci4gSW4gZWFjaCBydW4sIHRoZSBleHBsYW5hdG9yeSB2YXJpYWxibGVzIGFyZSBsYWdnZWQgdG8gYXZvaWQgbG9vay1haGVhZCBiaWFzLiBBbGwgb2YgdGhlIHJ1bnMgYW5hbHl6ZSB0aGUgZGlmZmVyZW5jZSBvZiB0aGUgbG9nIG9mIHRoZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlLiBUaGUgcmVhc29uIGZvciB1c2luZyB0aGUgZGlmZmVyZW5jZWQgbG9nIGlzIHRoYXQgaXQgY2xvc2VseSBhcHByb3hpbWF0ZXMgdGhlIHBlcmNlbnRhZ2UgY2hhbmdlIG9mIHRoZSBwcmljZSBmb3Igc21hbGwgY2hhbmdlcy4gQWxzbywgCgojIFJlc3VsdHMKCmBgYHtyfQojIFJlYWQgaW4gcmVsZXZhbnQgbGlicmFyaWVzCmxpYnJhcnkobWljcm9iZW5jaG1hcmspCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShxdWFudG1vZCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHRzZXJpZXMpCmxpYnJhcnkoem9vKQpsaWJyYXJ5KG1hZ3JpdHRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZm9ybWF0dGFibGUpCmxpYnJhcnkocXVhbnRyZWcpCmxpYnJhcnkoTVRTKQpsaWJyYXJ5KHBsb3QzRCkKbGlicmFyeShjaXRyKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQoKIyBTZXQgdXAgd29ya2luZyBkaXJlY3RvcnkKIyBzZXR3ZCgifi9Eb2N1bWVudHMvR2l0SHViL0NhdmlhUiIpCgojIHNvdXJjZSgnY2F2aWFyX1NNLlInKQpzb3VyY2UoJ34vRG9jdW1lbnRzL0dpdEh1Yi9DYXZpYVIvY2F2aWFyX1NNLlInKQpgYGAKCmBgYHtyfQojIFRoaXMgY29kZSBiZWxvdyBpcyBmb3IgdXNlIGluIHRoZSBDQVZpYVIgc2VjdGlvbnMuCmBgYAoKYGBge3J9CiMgSGVyZSBpcyBjb2RlIHRoYXQgSSdsbCB3cmFwIHNvbWUgcGFydHMgaW4gdG8gYXZvaWQgc3VwZXJmbHVvdXMgb3V0cHV0CnF1aWV0IDwtIGZ1bmN0aW9uKHgpIHsgCiAgc2luayh0ZW1wZmlsZSgpKSAKICBvbi5leGl0KHNpbmsoKSkgCiAgaW52aXNpYmxlKGZvcmNlKHgpKSAKfSAKYGBgCgoKYGBge3J9CiMnIFRoaXMgaXMgYSBmdW5jdGlvbiB3aGljaCBwdWxscyBkYXRhIGZvciB1c2UgaW4gdGhlIENBVmlhUiBtb2RlbAojJwojJyBAcGFyYW0gc3ltYm9sIC0gc3ltYm9sIHRvIHB1bGwKIycgQHBhcmFtIGNvbXBsX2Nhc2UgLSBkZWZhdWx0cyB0byB0cnVlLi4ub25seSBpbmNsdWRlcyBjb21wbGV0ZSBjYXNlcyBpbiB0aGUgZGF0YQojJyBAcGFyYW0gYWRqX2Nsb3NlIC0gdXNlIGFkanVzdGVkIGNsb3NpbmcgcHJpY2VzLiBEZWZhdWx0IGlzIHllcy4KIycgQHBhcmFtIGxvZ19yZXR1cm4gLSB1c2UgbG9nIHJldHVybj8gRGVmYXVsdCBpcyB5ZXMuCiMnCiMnIEByZXR1cm4gLSBhIGRhdGEgZnJhbWUgd2hpY2ggY2FuIGJlIGZlZCBpbnRvIGxhdGVyIGZ1bmN0aW9ucwojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIGRhdGFfcHVsbCgiU1BZIikKZGF0YV9wdWxsID0gZnVuY3Rpb24oc3ltYm9sLCBjb21wbF9jYXNlID0gMSwgYWRqX2Nsb3NlID0gMSwgbG9nX3JldHVybiA9IDEsIHN0YXJ0X2RhdGUgPSAiMTkwMC0wMS0wMSIsIGVuZF9kYXRlID0gU3lzLkRhdGUoKSl7CiAgIyBQdWxsIGluIGRhdGEgZnJvbSBxdWFudG1vZAogIHJlc3BvbnNlX3B1bGwgPSBnZXRTeW1ib2xzKHN5bWJvbCwgYXV0by5hc3NpZ24gPSBGQUxTRSwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpCiAgIyBHZXQgYWRqdXN0ZWQgY2xvc2luZyBwcmljZQogIGlmIChhZGpfY2xvc2UgPT0gVFJVRSl7CiAgICBkZiA9IEFkKHJlc3BvbnNlX3B1bGwpCiAgfSBlbHNlIHsKICAgIGRmID0gQ2wocmVzcG9uc2VfcHVsbCkKICB9CiAgIyBSZXR1cm4gY29tcGxldGUgY2FzZXMgb25seSAKICBpZiAoY29tcGxfY2FzZSA9PSBUUlVFKXsKICAgIGRmID0gZGZbY29tcGxldGUuY2FzZXMoZGYpLCBdCiAgfSBlbHNlewogICAgZGYgPSBkZgogIH0KICAjIENhbGN1bGF0ZSBsb2cgcmV0dXJuIG9mIGRhdGEKICBpZiAobG9nX3JldHVybiA9PSBUUlVFKXsKICAgIGxyID0gbG9nKGRmWywxXS9zaGlmdChkZlssMV0sIDEsIHR5cGUgPSAibGFnIikpCiAgICAjIENvbWJpbmUgZGF0YQogICAgZGZfb3V0ID0gY2JpbmQoZGYsIGxyKQogICAgIyBSZW5hbWUgdGhlIGRhdGEgCiAgICBjb2xuYW1lcyhkZl9vdXQpIDwtIGMoc3ltPXN5bWJvbCwgcGFzdGUwKHN5bWJvbCwgIl9sb2dfcmV0dXJuIikpCiAgfSBlbHNlewogICAgZGZfb3V0ID0gZGYKICB9CiAgIyBSZXR1cm4gZGF0YQogIHJldHVybihkZl9vdXQpCn0KCgpgYGAKCmBgYHtyfQojJyBQdWxsIHRoZSBkYXRhIGFuZCBydW4gdGhlIENBVmlhUiBmdW5jdGlvbiBvbiBpdAojJwojJyBAcGFyYW0gaW5wdXRfZGF0YSAtIGRhdGEgdG8gdXNlIGluIHRoZSBmdW5jdGlvbgojJyBAcGFyYW0gcmFuZ2VfZGF0YSAtIHJhbmdlIG9mIHRoZSBkYXRhIHRvIHVzZQojJwojJyBAcmV0dXJuIC0gYSBsaXN0IG9mIHZhbHVlcyBmcm9tIHRoZSBjYXZpYXIgZnVuY3Rpb24KIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBjYXZpYXJfcHVsbChzcHkpCmNhdmlhcl9wdWxsID0gZnVuY3Rpb24oaW5wdXRfZGF0YSwgcmFuZ2VfZGF0YSA9ICgyOmRpbShpbnB1dF9kYXRhKVsxXSkpewogICMgUnVuIHRoZSBjYXZpYXIgZGF0YQogIGNhdmlhciA8LSBjYXZpYXJPcHRpbShpbnB1dF9kYXRhW3JhbmdlX2RhdGEsMl0pCiAgcmV0dXJuKGNhdmlhcikKfQoKYGBgCgoKYGBge3J9CiMnIEZ1bmN0aW9uIGZvciBwcm9kdWNpbmcgcm9sbGluZyBwcmVkaWN0aW9ucwojJyBNb2RlbCAxID0gU3ltbWV0cmljIEFic29sdXRlIFZhbHVlLCAyID0gQXN5bW1ldHJpYyBzbG9wZSwgMyA9IEluZGlyZWN0IEdBUkNILCA0ID0gQWRhcHRpdmUKIycKIycgQHBhcmFtIGlucHV0X2RhdGEgLSBpbnB1dCBkYXRhIGZyb20gdGhlIHByZXZpb3VzIGZ1bmN0aW9uCiMnIEBwYXJhbSByYW5nZV9kYXRhIC0gcmFuZ2Ugb2YgdGhlIGRhdGEgdG8gY29uc2lkZXIKIycgQHBhcmFtIG5mY3N0IC0gbnVtYmVyIG9mIGZvcmVjYXN0cyB0byBtYWtlCiMnIEBwYXJhbSBtb2RlbCAtIG1vZGVsIHRvIHVzZSAoaW50ZWdlcnMgMSB0aHJvdWdoIDQpLiBEZWZhdWx0cyB0byAxLiAKIycgQHBhcmFtIGxldmVsIC0gbGV2ZWwgb2Ygc2lnbmlmaWNhbmNlIHRvIHVzZS4KIycgQHBhcmFtIEcgLSBhcmd1bWVudCBmb3IgdGhlIGsgcGFyYW1ldGVyIGluIHRoZSA0dGggbW9kZWwgKGFkYXB0aXZlKS4gRGVmYXVsdCBpcyA1CiMnCiMnIEByZXR1cm4gLSBhbiB4dHMgb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHJvbGxpbmcgQ0FWaWFSIHByZWRpY3Rpb25zCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gcm9sbGluZ19wcmVkaWN0aW9ucyhzcHksIG5mY3N0ID0gMjIpCnJvbGxpbmdfcHJlZGljdGlvbnMgPSBmdW5jdGlvbihpbnB1dF9kYXRhLCByYW5nZV9kYXRhID0gKDI6ZGltKGlucHV0X2RhdGEpWzFdKSwgbmZjc3QgPSAyNTAsIG1vZGVsID0xLCBsZXZlbCA9IDAuMDEsIEcgPSA1LCBjb2wgPSAyKXsKICAjIFJ1biB0aGUgdmFycHJlZGljdCBmdW5jdGlvbgogIHZhcnByZWRpY3QgPC0gcm9sbGFwcGx5cihpbnB1dF9kYXRhW3JhbmdlX2RhdGEsY29sXSwgbGVuZ3RoKHJhbmdlX2RhdGEpIC0gbmZjc3QsIGNhdmlhck9wdGltLCBtb2RlbCwgbGV2ZWwsIHByZWRpY3QgPSAxLCBrID0gRykgJT4lIGxhZwogICMgRWxpbWluYXRlIE5BcwogICMgcHJlZF9ub19uYSA9IG5hLm9taXQodmFycHJlZGljdCkKICAjIFJldHVybiB0aGUgZGF0YQogICMgcmV0dXJuKHByZWRfbm9fbmEpCiAgcmV0dXJuKHZhcnByZWRpY3QpCn0KCmBgYAoKYGBge3J9CiMnIEZ1bmN0aW9uIHRvIENhbGN1bGF0ZSBMb3NzIGZyb20gdGhlIGFib3ZlIHByZWRpY3Rpb25zCiMnCiMnIEBwYXJhbSBzeW1ib2wgLSBzeW1ib2wgdG8gd29yayB3aXRoIGZyb20gcXVhbnRtb2QuIE11c3QgYmUgaW4gcXVvdGF0aW9ucyB0byB3b3JrCiMnIEBwYXJhbSBzdGFydF9kdCAtIHN0YXJ0IGRhdGUgb2YgdGhlIGRhdGEgdG8gYnVpbGQgdGhlIGZvcmVjYXN0IG9uIAojJyBAcGFyYW0gZW5kX2R0IC0gZW5kIGRhdGUgb2YgdGhlIGRhdGEgdG8gYnVpbGQgdGhlIGZvcmVjYXN0IG9uICAKIycgQHBhcmFtIG5mY3N0IC0gbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHRvIHVzZSBpbiB0aGUgZm9yZWNhc3QKIycgQHBhcmFtIG1vZGVsIC0gbW9kZWwgdG8gdXNlLiBEZWZhdWx0cyB0byAxCiMnIEBwYXJhbSBsZXZlbCAtIGxldmVsIG9mIHNpZ25pZmljYW5jZS4gRGVmYXVsdHMgdG8gMSUKIycgQHBhcmFtIEcgLSBhcmd1bWVudCBmb3IgdGhlIGsgcGFyYW1ldGVyIGluIHRoZSA0dGggbW9kZWwgKGFkYXB0aXZlKS4gRGVmYXVsdCBpcyA1CiMnCiMnIEByZXR1cm4gLSBsb3NzIHVzaW5nIGFic29sdXRlIHZhbHVlCiMnIEBleHBvcnQgLSBhIHBsb3Qgb2YgdGhlIGRhdGEKIycKIycgQGV4YW1wbGVzCmxvc3NfY2FsY191diA9IGZ1bmN0aW9uKHN5bWJvbCwgc3RhcnRfZHQsIGVuZF9kdCwgbmZjc3QsIG1vZGVsID0gMSwgbGV2ZWwgPSAwLjAxLCBHID0gNSl7CiAgIyBQdWxsIGluIHRoZSBkYXRhCiAgcmF3X2RhdGEgPSBkYXRhX3B1bGwoc3ltYm9sLCBzdGFydF9kYXRlID0gc3RhcnRfZHQsIGVuZF9kYXRlID0gZW5kX2R0KQogICMgRm9yZWNhc3QgYmFzZWQgb24gdGhlIGRhdGEKICBmY3N0ID0gbmEub21pdChyb2xsaW5nX3ByZWRpY3Rpb25zKHJhd19kYXRhLCBuZmNzdCA9IG5mY3N0LCBtb2RlbCA9IG1vZGVsLCBsZXZlbCA9IGxldmVsLCBHID0gRykpKigtMSkKICAjIEV4dHJhY3QgYWN0dWFscwogIGFjdCA9IHRhaWwocmF3X2RhdGEsIG4gPSBuZmNzdClbLDJdCiAgIyBKb2luIHRoZSB0d28gdG9nZXRoZXIgYW5kIHJlbmFtZQogIGpvaW4gPSBtZXJnZShmY3N0LGFjdCxhbGw9VFJVRSkKICBjb2xuYW1lcyhqb2luKSA8LSBjKCJGY3N0X1ZhUiIsICJBY3RfUmV0dXJuIikKICAjIHByaW50KGpvaW4pCiAgIyBDYWxjdWxhdGUgdGhlIGxvc3NlcwogIGxvc3MgPSBhYnMoc3VtKGlmZWxzZShhY3QgPiBmY3N0LCBsZXZlbCwgKC0xKSooMS1sZXZlbCkpKSkKICAjIFBsb3QgdGhlIGRhdGEKICBwbG90ID0gcGxvdC54dHMoam9pbiwgY29sID0gYygicmVkIiwgImJsYWNrIiksIGx0eSA9IGMoMiwxKSwgbWFpbiA9ICJMb2cgUmV0dXJuIGZyb20gdGhlIFNQWSB2cy4gRmNzdC4gVmFSIixncmlkLmNvbCA9IE5BLCBsZWdlbmQubG9jID0gImJvdHRvbWxlZnQiKQogIHJldHVybihsaXN0KGxvc3MsIHBsb3QsIGFjdCwgZmNzdCkpCn0KCmBgYAoKCmBgYHtyLCBjYWNoZSA9IFRSVUV9CiMnIFRoaXMgaXMgYSBmdW5jdGlvbiB3aGljaCBjcmVhdGVzIGEgZGF0YSBmcmFtZSBmb3IgdGhlIHJlc3BvbnNlIGFuZCBleHBsYW5hdG9yeSB2YXJpYWJsZXMgdGhhdCB3ZSdsbCBmZWVkIGludG8gdGhlIGRpZmZ1c2lvbiBpbmRleAojJwojJyBAcGFyYW0gc3ltYm9sX2xpc3QgLSBhIGxpc3Qgb2Ygc3ltYm9scyByZWNvZ25pemFibGUgYnkgdGhlIAojJyBAcGFyYW0gcmVzcF92YXIgLSB0aGUgcmVzcG9uc2UgdmFyaWFibGUgd2UnZCBsaWtlIHRvIGZvcmVjYXN0OyBkZWZhdWx0IGlzIFNQWQojJyBAcGFyYW0gY29tcGxfY2FzZSAtIGRlZmF1bHRzIHRvIHRydWUuLi5vbmx5IGluY2x1ZGVzIGNvbXBsZXRlIGNhc2VzIGluIHRoZSBkYXRhCiMnIEBwYXJhbSBhZGpfY2xvc2UgLSB1c2UgYWRqdXN0ZWQgY2xvc2luZyBwcmljZXMgZm9yIHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZXM/IGRlZmF1bHQgaXMgMSBmb3IgWUVTCiMnIEBwYXJhbSByZXNwX2Fkal9jbG9zZSAtIHVzZSBhZGp1c3RlZCBjbG9zaW5nIHByaWNlcyBmb3IgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcz8gZGVmYXVsdCBpcyAxIGZvciBZRVMKIycgQHBhcmFtIHN0YXJ0X2RhdGUgLSBzdGFydGluZyBkYXRhIHRvIHVzZQojJyBAcGFyYW0gZW5kX2RhdGUgLSBlbmRpbmcgZGF0ZSBvZiB0aGUgZGF0YQojJyBAcGFyYW0gbGFnX3ByZWQgLSBkbyB3ZSBsYWcgdGhlIHByZWRpY3Rpb25zPyBJdCBpcyBTVFJPTkdMWSByZWNvbW1lbmRlZCB0aGF0IHRoaXMgaXMgMAojJwojJyBAcmV0dXJuIC0gYSBkYXRhIGZyYW1lIHdoaWNoIGNhbiBiZSBmZWQgaW50byB0aGUgU1dmb3JlIGZ1bmN0aW9uCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gZGlmZl9pbmRleF9kZihjKCJYTEYiLCAiWExFIiwgIlBTQ1QiLCAiWExWIiwgIlZQVSIsICJYTFAiLCAiSUdGIiwgIlhXRUIiLCAiUFBUWSIpKQpkaWZmX2luZGV4X2RmID0gZnVuY3Rpb24oc3ltYm9sX2xpc3QsIHJlc3BfdmFyID0gIlNQWSIsIGNvbXBsX2Nhc2UgPSAxLCBhZGpfY2xvc2UgPSAxLCByZXNwX2Fkal9jbG9zZSA9IDEsIHN0YXJ0X2RhdGUgPSAiMTkwMC0wMS0wMSIsIGVuZF9kYXRlID0gU3lzLkRhdGUoKSwgbGFnX3ByZWQgPSAxKXsKICAjIFB1bGwgaW4gcmVzcG9uc2UgdmFyaWFibGUKICByZXNwb25zZV9wdWxsID0gZ2V0U3ltYm9scyhyZXNwX3ZhciwgYXV0by5hc3NpZ24gPSBGQUxTRSwgZnJvbSA9IHN0YXJ0X2RhdGUsIHRvID0gZW5kX2RhdGUpCiAgIyBHZXQgYWRqdXN0ZWQgY2xvc2luZyBwcmljZQogIGlmIChyZXNwX2Fkal9jbG9zZSA9PSBUUlVFKXsKICAgIGRpZmZfZGYgPSBBZChyZXNwb25zZV9wdWxsKQogIH0gZWxzZSB7CiAgICBkaWZmX2RmID0gQ2wocmVzcG9uc2VfcHVsbCkKICB9CiAgIyBMb29wIHRocm91Z2ggdGhlIHN5bWJvbHMgYW5kIGpvaW4gaW4gZGF0YQogIGZvciAoaSBpbiAxOmxlbmd0aChzeW1ib2xfbGlzdCkpewogICAgIyBQdWxsIGNsb3NpbmcgcHJpY2UKICAgIGV4cGxfcHVsbCA9IGdldFN5bWJvbHMoc3ltYm9sX2xpc3RbaV0sIGF1dG8uYXNzaWduID0gRkFMU0UsIGZyb20gPSBzdGFydF9kYXRlLCB0byA9IGVuZF9kYXRlKQogICAgIyBFeHRyYWN0IGNsb3NpbmcgcHJpY2UgLSA0dGggZWxlbWVudAogICAgaWYgKGFkal9jbG9zZSA9PSBUUlVFKXsKICAgICAgZXhwbF9jbCA9IEFkKGV4cGxfcHVsbCkKICAgIH0gZWxzZSB7CiAgICAgIGV4cGxfY2wgPSBDbChleHBsX3B1bGwpCiAgICB9CiAgICAjIE5ldyBjb2RlIGZvciA0LjE2LjIwMjAgLSBsYWcgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcwogICAgaWYgKGxhZ19wcmVkID09IFRSVUUpewogICAgICAjIExhZyB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGJ5IDEKICAgICAgbGFnX2V4cCA9IGxhZyhleHBsX2NsLCAxKQogICAgICAjIEFwcGVuZCB0aGUgZmlyc3QgbGFnIHRvIHRoZSBkYXRhIGZyYW1lCiAgICAgIGRpZmZfZGYgPSBtZXJnZShkaWZmX2RmLCBsYWdfZXhwLCBqb2luID0gImxlZnQiLCBmaWxsID0gTkEpCiAgICB9IGVsc2V7CiAgICAgICMgUmV0dXJuIHRoZSBkYXRhIGZyYW1lIHdpdGhvdXQgbGFncwogICAgICBkaWZmX2RmID0gbWVyZ2UoZGlmZl9kZiwgZXhwbF9jbCwgam9pbiA9ICJsZWZ0IiwgZmlsbCA9IE5BKQogICAgfQogIH0KICBpZiAobGFnX3ByZWQgPT0gVFJVRSl7CiAgICAjIENob3Agb2ZmIHRoZSBmaXJzdCByb3cKICAgIGRpZmZfZGYgPSBkaWZmX2RmWy0xLF0KICB9CiAgZWxzZSB7CiAgICBwcmludCgiUExFQVNFIE5PVEUgLSB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGluIHRoaXMgREYgYXJlIE5PVCBsYWdnZWQuIEJlIGNhcmVmdWwgdG8gYXZvaWQgbG9vay1haGVhZCBiaWFzISIpCiAgfQogICMgUmV0dXJuIGNvbXBsZXRlIGNhc2VzIG9ubHkgCiAgaWYgKGNvbXBsX2Nhc2UgPT0gVFJVRSl7CiAgICBkaWZmX2RmX291dCA9IGRpZmZfZGZbY29tcGxldGUuY2FzZXMoZGlmZl9kZiksIF0KICB9IGVsc2V7CiAgICBkaWZmX2RmX291dCA9IGRpZmZfZGYKICB9CiAgCiAgcmV0dXJuKGRpZmZfZGZfb3V0KQp9CgpgYGAKCmBgYHtyLCBjYWNoZSA9IFRSVUV9CiMnIENvbnZlcnRzIGEgZGlmZl9kZiBpbnRvIGEgZGF0YSBmcmFtZSB3aXRoIGFwcHJveGltYXRlIHBlcmNlbnRhZ2UgY2hhbmdlcyBkaWZmKGxvZyhkaWZmX2RmKSkKIycKIycgQHBhcmFtIGRpZmZfZGYgLSBvdXRwdXQgb2YgdGhlIGRpZmZfaW5kZXhfZGYgZnVuY3Rpb24gd2l0aCBjb21wbGV0ZSBjYXNlcwojJwojJyBAcmV0dXJuIC0gcmV0dW5zIHRoZSBkaWZmZXJlbmNlZCBkYXRhCiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzIC0gcGNfZGlmZl9pbmRleCh0ZXN0X2NvbXBsKSAKCnBjX2RpZmZfaW5kZXggPSBmdW5jdGlvbihkaWZmX2RmKXsKICAjIERpZmZlcmVuY2UgdGhlIGxvZyBvZiB0aGUgZGF0YQogIHBjX2RpZmZfaW5kZXggPSBkaWZmKGxvZyhkaWZmX2RmKSkKICAjIFJlbW92ZSB0aGUgZmlyc3Qgcm93CiAgcGNfZGlmZl9pbmRleF9vdXQgPSBwY19kaWZmX2luZGV4Wy0xLF0KICByZXR1cm4ocGNfZGlmZl9pbmRleF9vdXQpCn0KCmBgYAoKCmBgYHtyfQojJyBCZWxvdyBpcyB0aGUgbW9kaWZpZWQgZGlmZnVzaW9uIGluZGV4IGNvZGUuCiMnCiMnIEBwYXJhbSB5IC0gcmVzcG9uc2UgdmFyaWFibGUKIycgQHBhcmFtIHggLSBwcmVkaWN0b3IgdmFyaWFibGVzCiMnIEBwYXJhbSBvcmlnIC0gZm9yZWNhc3Qgb3JpZ2luCiMnIEBwYXJhbSBtIC0gbnVtYmVyIG9mIGRpZmZ1c2lvbiBpbmRleGVzIHVzZWQKIycgQHBhcmFtIHRhdSAtIFZhUiBsZXZlbCB0byB1c2U7IG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxCiMnIEBwYXJhbSBlbmQgLSBzcGVjaWZpZXMgYW4gYWx0ZXJuYXRlIGVuZGluZyB2YWx1ZQojJyBAcGFyYW0gcHJpbnRfbWRsIC0gcHJpbnQgdGhlIG1vZGVsIHN1bW1hcnkgYW5kIHRoZSBNU0UKIycKIycgQHJldHVybiAtIHJldHVybnMgYSBsaXN0IG9mIHZhcmlhYmxlcyBmb3IgdXNlIGluIHRoZSBkaWZmdXNpb24gaW5kZXgKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMKbW9kX2RpID0gZnVuY3Rpb24gKHksIHgsIG9yaWcsIG0sIHRhdSwgZW5kID0gTlVMTCwgcHJpbnRfbWRsID0gMCkgCnsKICAjIENvbnZlcnRzIHRoZSByZXNwb25zZSB2YXJpYWJsZXMgaW50byBhIG1hdHJpeAogIGlmICghaXMubWF0cml4KHgpKSAKICAgICAgeCA9IGFzLm1hdHJpeCh4KQogICMgblQgaXMgbnVtYmVyIG9mIHQgdGltZS1zdGVwcwogIG5UID0gZGltKHgpWzFdCiAgIyBBZGQgYSBsaW5lIHRvIGVzdGFibGlzaCB0aGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHVzZWQgaW4gdGhlIHRlc3QuCiAgaWYgKGlzLm51bGwoZW5kKSAhPSBUUlVFKXsKICAgIG5UID0gZW5kCiAgfQogICMgayBpcyB0aGUgbnVtYmVyIG9mIGRpZmZ1c2lvbiBpbmRpY2VzIHVzZWQKICBrID0gZGltKHgpWzJdCiAgIyBTYW5pdHkgY2hlY2tzIHRvIGVuc3VyZSB0aGF0IHRoZSBvcmlnaW4gaXNuJ3QgcGFzdCB0aGUgbnVtYmVyIG9mIHRpbWUgcG9pbnRzCiAgaWYgKG9yaWcgPiBuVCkgCiAgICAgIG9yaWcgPSBuVAogICMgTWFrZXMgc3VyZSB0aGF0IHRoZXJlIGFyZW4ndCBtb3JlIHByZWRpY3RvcnMgdGhhbiB0aGVyZSB2YXJpYWJsZXMgaW4gdGhlIGRhdGFzZXQKICBpZiAobSA+IGspIAogICAgICBtID0gawogICMgTWFrZXMgc3VyZSB0aGVyZSBhcmUgYXQgbGVhc3Qgc29tZSB2YXJpYWJsZXMKICBpZiAobSA8IDEpIAogICAgICBtID0gMQogICMgU3ViZGl2aWRlcyB0aGUgZGF0YWZyYW1lCiAgeDEgPSB4WzE6b3JpZywgXQogICMgQ2FsY3VsYXRlcyBtZWFucyBvZiBlYWNoIHJvdwogIG1lID0gYXBwbHkoeDEsIDIsIG1lYW4pCiAgIyBDYWxjdWxhdGVzIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgZWFjaCBjb2x1bW4KICBzZSA9IHNxcnQoYXBwbHkoeDEsIDIsIHZhcikpCiAgIyBDcmVhdGVzIGEgbWF0cml4IHgxLCB3aGljaCBub3JtYWxpemVzIGFsbCB0aGUgY29sdW1ucy4gCiAgIyBUaGlzIG1heSBiZSBhbiBpc3N1ZSBzaW5jZSBpdCBhc3N1bWVzIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBpcyBzdWZmaWNpZW50bHkgZGVzY3JpYmVkIGJ5IHRoZSBmaXJzdCB0d28gbW9tZW50cwogIHgxID0geAogIGZvciAoaSBpbiAxOmspIHsKICAgICAgeDFbLCBpXSA9ICh4MVssIGldIC0gbWVbaV0pL3NlW2ldCiAgfQogIFYxID0gY292KHgxWzE6b3JpZywgXSkKICAjIFBlcmZvcm1zIGFuIGVpZ2VuIGRlY29tcG9zaXRpb24KICBtMSA9IGVpZ2VuKFYxKQogICMgU2VsZWN0cyBlaWdlbnZhbHVlcwogIHNkZXYgPSBtMSR2YWx1ZXMKICAjIFNlbGVjdHMgZWlnZW52ZWN0b3JzCiAgTSA9IG0xJHZlY3RvcnMKICAjIE1ha2VzIGEgc21hbGxlciBtYXRyaXgKICBNMSA9IE1bLCAxOm1dCiAgIyBUaGlzIGlzIHRoZSBkaWZmdXNpb24gaW5kZXggbW9kZWwgLSBbb3JpZyB4IHBdKltwIHggbV0gPSBbb3JpZyB4IG1dCiAgRGluZGV4ID0geDEgJSolIE0xCiAgIyBDdXQgZG93biBib3RoIHRoZSByZXNwb25zZSBhbmQgcHJlZGljdG9ycyB0byBiZSBhIHJlYXNvbmFibGUgc2l6ZQogIHkxID0geVsxOm9yaWddCiAgREYgPSBEaW5kZXhbMTpvcmlnLCBdCiAgIyBBcHBseSB0aGUgbGluZWFyIG1vZGVsIC0gSEVSRSBpcyB0aGUga2V5LgogICMgbW0gPSBsbSh5MSB+IERGKSAtIG9sZCBmdW5jdGlvbgogIG1tID0gcnEoeTEgfiBERiwgdGF1ID0gdGF1KQogICMgUHJpbnQgdGhlIGRhdGEKICBpZiAocHJpbnRfbWRsID09IDEpewogICAgcHJpbnQoc3VtbWFyeShtbSkpCiAgfQogICMgUHV0cyBjb2VmZmljaWVudHMgaW4gYSBtYXRyaXgKICBjb2VmID0gbWF0cml4KG1tJGNvZWZmaWNpZW50cywgKG0gKyAxKSwgMSkKICAjIEluaXRpYWxpemVzIHloYXQgdmFyaWFibGVzIGFuZCBNU0UKICB5aGF0ID0gTlVMTAogIE1TRSA9IE5VTEwKICBpZiAob3JpZyA8IG5UKSB7CiAgICAjIENyZWF0ZXMgYSBuZmNzdCBieSAobSsxKSBtYXRyaXgKICAgIG5ld3ggPSBjYmluZChyZXAoMSwgKG5UIC0gb3JpZykpLCBEaW5kZXhbKG9yaWcgKyAxKTpuVCwgCiAgICAgICAgXSkKICAgICMgW25mY3N0eChtKzEpXSpbKG0rMSl4MV0gPSBbbmZjc3R4MV0KICAgIHloYXQgPSBuZXd4ICUqJSBjb2VmCiAgICAjIENhbGN1bGF0ZXMgZXJyb3JzCiAgICBlcnIgPSB5WyhvcmlnICsgMSk6blRdIC0geWhhdAogICAgTVNFID0gbWVhbihlcnJeMikKICAgIGlmIChwcmludF9tZGwgPT0gMSl7CiAgICAgIGNhdCgiTVNFIG9mIG91dC1vZi1zYW1wbGUgZm9yZWNhc3RzOiAiLCBNU0UsICJcbiIpCiAgICB9CiAgfQogIFNXZm9yZSA8LSBsaXN0KGNvZWYgPSBjb2VmLCB5aGF0ID0geWhhdCwgTVNFID0gTVNFLCBsb2FkaW5ncyA9IE0xLCAKICAgICAgREZpbmRleCA9IERpbmRleCkKfQoKYGBgCgoKYGBge3J9CiMnIEJlbG93IGlzIHRoZSBtb2RpZmllZCBkaWZmdXNpb24gaW5kZXggY29kZSB0byBpbmNsdWRlIGxhZ2dlZCB2YXJpYWJsZXMuCiMnCiMnIEBwYXJhbSB5IC0gcmVzcG9uc2UgdmFyaWFibGUKIycgQHBhcmFtIHggLSBwcmVkaWN0b3IgdmFyaWFibGVzCiMnIEBwYXJhbSBvcmlnIC0gZm9yZWNhc3Qgb3JpZ2luCiMnIEBwYXJhbSBtIC0gbnVtYmVyIG9mIGRpZmZ1c2lvbiBpbmRleGVzIHVzZWQKIycgQHBhcmFtIHRhdSAtIFZhUiBsZXZlbCB0byB1c2U7IG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxCiMnIEBwYXJhbSBhcl90ZiAtIEFSIHRyYW5zZm9ybWF0aW9uIHR5cGUuICgxIC0gbm8gdHJhbnNmb3JtYXRpb24sCiMnIDIgLSBhYnNvbHV0ZSB2YWx1ZSwgMyAtIGFzeW1tZXRyaWMgc2xvcGUpCiMnIEBwYXJhbSBwIC0gbnVtYmVyIG9mIEFSIGxhZ3MgdG8gaW5jbHVkZS4gRGVmYXVsdCBpcyBvbmUuCiMnIEBwYXJhbSBwcmludF9tZGwgLSBvcHRpb24gdG8gcHJpbnQgdGhlIG1vZGVsIHN1bW1hcnkgdG8gbWFrZSBzdXJlIGV2ZXJ5dG5pbmcgaXMgb2suIDAgaXMgZGVmYXVsdC4KIycgQHBhcmFtIG1vZGVsIC0gbW9kZWwgdHlwZSAoMSAtIFNBViwgMiAtIEFTLCAzIC0gR0FSQ0gsIDQgLSBBREFQVElWRSkgCiMnCiMnIEByZXR1cm4gLSByZXR1cm5zIGEgbGlzdCBvZiB2YXJpYWJsZXMgZm9yIHVzZSBpbiB0aGUgZGlmZnVzaW9uIGluZGV4CiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzCm1vZF9kaV93bCA9IGZ1bmN0aW9uICh5LCB4LCBvcmlnLCBtLCB0YXUsIGFyX3RmID0gMSwgcCA9IDEsIHByaW50X21kbCA9IDAsIG1vZGVsID0gMSwgZW5kID0gTlVMTCkgCnsKICAjIENvbnZlcnRzIHRoZSByZXNwb25zZSB2YXJpYWJsZXMgaW50byBhIG1hdHJpeAogIGlmICghaXMubWF0cml4KHgpKSAKICAgICAgeCA9IGFzLm1hdHJpeCh4KQogICMgblQgaXMgbnVtYmVyIG9mIHQgdGltZS1zdGVwcwogIG5UID0gZGltKHgpWzFdCiAgIyBBZGQgYSBsaW5lIHRvIGVzdGFibGlzaCB0aGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzIHVzZWQgaW4gdGhlIHRlc3QuCiAgaWYgKGlzLm51bGwoZW5kKSAhPSBUUlVFKXsKICAgIG5UID0gZW5kCiAgfQogICMgayBpcyB0aGUgbnVtYmVyIG9mIGRpZmZ1c2lvbiBpbmRpY2VzIHVzZWQKICBrID0gZGltKHgpWzJdCiAgIyBTYW5pdHkgY2hlY2tzIHRvIGVuc3VyZSB0aGF0IHRoZSBvcmlnaW4gaXNuJ3QgcGFzdCB0aGUgbnVtYmVyIG9mIHRpbWUgcG9pbnRzCiAgaWYgKG9yaWcgPiBuVCkgCiAgICAgIG9yaWcgPSBuVAogICMgTWFrZXMgc3VyZSB0aGF0IHRoZXJlIGFyZW4ndCBtb3JlIHByZWRpY3RvcnMgdGhhbiB0aGVyZSB2YXJpYWJsZXMgaW4gdGhlIGRhdGFzZXQKICBpZiAobSA+IGspIAogICAgICBtID0gawogICMgTWFrZXMgc3VyZSB0aGVyZSBhcmUgYXQgbGVhc3Qgc29tZSB2YXJpYWJsZXMKICBpZiAobSA8IDEpIAogICAgICBtID0gMQogICMgU3ViZGl2aWRlcyB0aGUgZGF0YWZyYW1lCiAgeDEgPSB4WzE6b3JpZywgXQogICMgQ2FsY3VsYXRlcyBtZWFucyBvZiBlYWNoIHJvdwogIG1lID0gYXBwbHkoeDEsIDIsIG1lYW4pCiAgIyBDYWxjdWxhdGVzIHN0YW5kYXJkIGRldmlhdGlvbnMgb2YgZWFjaCBjb2x1bW4KICBzZSA9IHNxcnQoYXBwbHkoeDEsIDIsIHZhcikpCiAgIyBDcmVhdGVzIGEgbWF0cml4IHgxLCB3aGljaCBub3JtYWxpemVzIGFsbCB0aGUgY29sdW1ucy4gCiAgIyBUaGlzIG1heSBiZSBhbiBpc3N1ZSBzaW5jZSBpdCBhc3N1bWVzIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBpcyBzdWZmaWNpZW50bHkgZGVzY3JpYmVkIGJ5IHRoZSBmaXJzdCB0d28gbW9tZW50cwogIHgxID0geAogIGZvciAoaSBpbiAxOmspIHsKICAgICAgeDFbLCBpXSA9ICh4MVssIGldIC0gbWVbaV0pL3NlW2ldCiAgfQogIFYxID0gY292KHgxWzE6b3JpZywgXSkKICAjIFBlcmZvcm1zIGFuIGVpZ2VuIGRlY29tcG9zaXRpb24KICBtMSA9IGVpZ2VuKFYxKQogICMgU2VsZWN0cyBlaWdlbnZhbHVlcwogIHNkZXYgPSBtMSR2YWx1ZXMKICAjIFNlbGVjdHMgZWlnZW52ZWN0b3JzCiAgTSA9IG0xJHZlY3RvcnMKICAjIE1ha2VzIGEgc21hbGxlciBtYXRyaXgKICBNMSA9IE1bLCAxOm1dCiAgIyBUaGlzIGlzIHRoZSBkaWZmdXNpb24gaW5kZXggbW9kZWwgLSBbb3JpZyB4IHBdKltwIHggbV0gPSBbb3JpZyB4IG1dCiAgRGluZGV4ID0geDEgJSolIE0xCiAgIyBDdXQgZG93biBib3RoIHRoZSByZXNwb25zZSBhbmQgcHJlZGljdG9ycyB0byBiZSBhIHJlYXNvbmFibGUgc2l6ZQogIHkxID0geVsxOm9yaWddCiAgREYgPSBEaW5kZXhbMTpvcmlnLCBdCiAgIyBDb3B5IHRoZSBkYXRhIGZyYW1lCiAgREZfd2wgPSBEaW5kZXgKICAjIExhZyB0aGUgeS12YXJpYWJsZQogIGZvciAoaSBpbiAxOnApewogICAgIyBDcmVhdGUgYSBsYWdnZWQgdmFyaWFibGUKICAgIGxhZ192YXIgPSBsYWcoeSwgaSkKICAgICMgQXBwZW5kIHRoZSBmaXJzdCBsYWcgdG8gdGhlIGRhdGEgZnJhbWUKICAgIERGX3dsID0gY2JpbmQoREZfd2wsbGFnX3ZhcikKICB9CiAgIyBJZGVudGlmeSB0aGUgcmlnaHQgY29sdW1ucwogIGxfYXIgPSBuY29sKERGX3dsKQogIGZfYXIgPSBsX2FyIC0gcCArIDEKICAjIEtlZXAgdGhlIGxhc3QgY29sdW1ucyBrZXB0IHRvIHRoZSBzaWRlCiAgYWxsX2xhZyA9IERGX3dsWywoZl9hcjpsX2FyKV0KICAjIEN1dCBvZmYgdGhlIGZpcnN0IHJvdyB0byBhdm9pZCBOQSdzCiAgREZfdHJpbSA9IERGX3dsWzE6b3JpZyxdCiAgIyBSZW5hbWUgdGhlIGNvbHVtbnMKICAjIEhlcmUncyB0aGUgbmV3IGZ1bmN0aW9uIHdpdGggYW4gdW50cmFuc2Zvcm1lZCBBUihwKSBsYWcKICBpZiAoYXJfdGYgPT0gMSl7CiAgICAjIEluY29ycG9yYXRlIGV2ZXJ5dGhpbmcgaW4gdG8gYW4gaW5wdXQgZGF0YSBmcmFtZQogICAgZGZfaW4gPSBjYmluZCh5MVstKDE6cCldLCBERl90cmltWy0oMTpwKSxdKQogICAgIyBSZW5hbWUgdGhlIGNvbHVtbnMKICAgICMgSW5pdGlhbGl6ZSBhIGNoYXJhY3RlciB2ZWN0b3IKICAgIG52ZWMgPSBjKHJlcCgwLCAxK20rcCkpCiAgICAjIFBvcHVsYXRlIHRoZSB2ZWN0b3IgLSBmaXJzdCB2YWx1ZSBpcyB0aGUgcmVzcG9uc2UKICAgIG52ZWNbMV0gPC0gbmFtZXMoeSkKICAgICMgTmV4dCBhcmUgdGhlIGRpZmZ1c2lvbiBpbmRpY2VzCiAgICBmb3IgKGkgaW4gMTptKXsKICAgICAgbnZlY1tpKzFdID0gcGFzdGUwKCJEaWZmX0luZGV4XyIsIGkpCiAgICB9CiAgICAjIE5leHQgYXJlIHRoZSBsYWdnZWQgdmFyaWFibGVzCiAgICBmb3IgKGkgaW4gMTpwKXsKICAgICAgbnZlY1tpKzErbV0gPSBwYXN0ZTAoIkxhZ18iLCBpKQogICAgfQogICAgIyBBc3NpZ24gdGhlIG5hbWVzCiAgICBuYW1lcyhkZl9pbikgPC0gbnZlYwogICAgIyBSdW4gdGhlIG1vZGVsCiAgICBtbSA9IHJxKGRmX2luWywxXSB+IGRmX2luWywtMV0sIHRhdSA9IHRhdSkKICB9CiAgIyBIZXJlJ3MgdGhlIG5ldyBmdW5jdGlvbiB3aXRoIGFuIFNBViBBUihwKSBsYWcKICBpZiAoYXJfdGYgPT0gMil7CiAgICAjIEluY29ycG9yYXRlIGV2ZXJ5dGhpbmcgaW4gdG8gYW4gaW5wdXQgZGF0YSBmcmFtZQogICAgZGZfaW4gPSBjYmluZCh5MVstKDE6cCldLCBERl90cmltWy0oMTpwKSwtKGZfYXI6bF9hcildLCBhYnMoREZfdHJpbVstKDE6cCksKGZfYXI6bF9hcildKSkKICAgICMgUmVuYW1lIHRoZSBjb2x1bW5zCiAgICAjIEluaXRpYWxpemUgYSBjaGFyYWN0ZXIgdmVjdG9yCiAgICBudmVjID0gYyhyZXAoMCwgMSttK3ApKQogICAgIyBQb3B1bGF0ZSB0aGUgdmVjdG9yIC0gZmlyc3QgdmFsdWUgaXMgdGhlIHJlc3BvbnNlCiAgICBudmVjWzFdIDwtIG5hbWVzKHkpCiAgICAjIE5leHQgYXJlIHRoZSBkaWZmdXNpb24gaW5kaWNlcwogICAgZm9yIChpIGluIDE6bSl7CiAgICAgIG52ZWNbaSsxXSA9IHBhc3RlMCgiRGlmZl9JbmRleF8iLCBpKQogICAgfQogICAgIyBOZXh0IGFyZSB0aGUgbGFnZ2VkIHZhcmlhYmxlcwogICAgZm9yIChpIGluIDE6cCl7CiAgICAgIG52ZWNbaSsxK21dID0gcGFzdGUwKCJMYWdfIiwgaSkKICAgIH0KICAgICMgQXNzaWduIHRoZSBuYW1lcy4gTm90ZSB0aGF0IHRoaXMgaXMgYSBtYXRyaXgKICAgIG5hbWVzKGRmX2luKSA8LSBudmVjCiAgICAjIFJ1biB0aGUgbW9kZWwKICAgIG1tID0gcnEoZGZfaW5bLDFdIH4gZGZfaW5bLC0xXSwgdGF1ID0gdGF1KQogIH0KICAjIEhlcmUncyB0aGUgbmV3IGZ1bmN0aW9uIHdpdGggYW4gYXN5bW1ldHJpYyBzbG9wZSBmb3IgdGhlIEFSKDEpIGxhZwogICMgSW5kaWNhdG9yOyAwIGlmIHBlcmNlbnQgY2hhbmdlIGlzIG5lZ2F0aXZlLCAxIGlmIGl0J3MgcG9zaXRpdmUKICAjIGluZGkgPSBpZmVsc2UoREZfdHJpbVssYXJdIDwgMCwgMCwgMSkKICBpZiAoYXJfdGYgPT0gMyl7CiAgICAjIENyZWF0ZSBhIG1hdHJpeCBvZiBpbmRpY2F0b3JzCiAgICBpbmRpX21hdCA9IG1hdHJpeCgwLCBucm93KERGX3dsKSwgcCkKICAgICMgR2VuZXJhbGl6ZSB0aGUgYWJvdmUgY29kZQogICAgZm9yIChpIGluIDE6cCl7CiAgICAgICMgUG9wdWxhdGUgdGhlIGluZGljYXRvcgogICAgICBpbmRpX21hdFssaV0gPSBpZmVsc2UoREZfd2xbLGZfYXIgKyBpIC0gMV0gPCAwLCAwLCAxKQogICAgfQogIH0KICAjIEZpdHRpbmcgdGhlIHJlZ3Jlc3Npb24KICBpZiAoYXJfdGYgPT0gMyl7CiAgICAjIEluY29ycG9yYXRlIGV2ZXJ5dGhpbmcgaW4gdG8gYW4gaW5wdXQgZGF0YSBmcmFtZQogICAgZGZfaW4gPSBjYmluZCh5MVstKDE6cCldLCBERl90cmltWy0oMTpwKSwtKGZfYXI6bF9hcildLCBERl90cmltWy0oMTpwKSwoZl9hcjpsX2FyKV0sIGluZGlfbWF0WygocCsxKTpvcmlnKSxdKQogICAgIyBSZW5hbWUgdGhlIGNvbHVtbnMKICAgICMgSW5pdGlhbGl6ZSBhIGNoYXJhY3RlciB2ZWN0b3IKICAgIG52ZWMgPSBjKHJlcCgwLCAxK20rMipwKSkKICAgICMgUG9wdWxhdGUgdGhlIHZlY3RvciAtIGZpcnN0IHZhbHVlIGlzIHRoZSByZXNwb25zZQogICAgbnZlY1sxXSA8LSBuYW1lcyh5KQogICAgIyBOZXh0IGFyZSB0aGUgZGlmZnVzaW9uIGluZGljZXMKICAgIGZvciAoaSBpbiAxOm0pewogICAgICBudmVjW2krMV0gPSBwYXN0ZTAoIkRpZmZfSW5kZXhfIiwgaSkKICAgIH0KICAgICMgTmV4dCBhcmUgdGhlIGxhZ2dlZCB2YXJpYWJsZXMKICAgIGZvciAoaSBpbiAxOnApewogICAgICBudmVjW2krMSttXSA9IHBhc3RlMCgiTGFnXyIsIGkpCiAgICB9CiAgICAjIExhc3QgYXJlIHRoZSBwb3NpdGl2ZSBpbmRpY2F0b3IgdmFyaWFibGVzCiAgICBmb3IgKGkgaW4gMTpwKXsKICAgICAgbnZlY1tpKzErbStwXSA9IHBhc3RlMCgiUG9zX1ZhbF9mb3JfTGFnXyIsIGkpCiAgICB9CiAgICAjIEFzc2lnbiB0aGUgbmFtZXMuIE5vdGUgdGhhdCB0aGlzIGlzIGEgbWF0cml4CiAgICBuYW1lcyhkZl9pbikgPC0gbnZlYwogICAgIyBSdW4gdGhlIG1vZGVsCiAgICBtbSA9IHJxKGRmX2luWywxXSB+IGRmX2luWywtMV0sIHRhdSA9IHRhdSkKICAgICMgbW0gPSBycSh5MVstKDE6cCldIH4gREZfdHJpbVstKDE6cCksLShmX2FyOmxfYXIpXSArIERGX3RyaW1bLSgxOnApLChmX2FyOmxfYXIpXSArIGluZGlfbWF0WygocCsxKTpvcmlnKSxdLCB0YXUgPSB0YXUpCiAgICAjIEFkZCBhIGRpZmZlcmVudCBsaW5lIHRvIGFjY291bnQgZm9yIHRoZSBpbmRpY2F0b3IgdmFyaWFibGUKICAgICMgaW50ZXJjZXB0ICsgbSArIDIqbmxhZyB0byBhY2NvdW50IGZvciB0aGUgbnVtYmVyIG9mIGluZGljYXRvciB2YXJpYWJsZXMKICAgIGNvZWYgPSBtYXRyaXgobW0kY29lZmZpY2llbnRzLCAoMSArIG0gKyAyKnApLCAxKQogIH0KICBpZiAocHJpbnRfbWRsID09IDEpewogICAgcHJpbnQoc3VtbWFyeShtbSkpCiAgfQogICMgUHV0cyBjb2VmZmljaWVudHMgaW4gYSBtYXRyaXggLSBhZGRlZCB0aGUgQVIgdGVybXMKICAjIGNvZWYgPSBtYXRyaXgobW0kY29lZmZpY2llbnRzLCAobSArIDEpLCAxKQogIGlmIChhcl90ZiAhPSAzKXsKICAgIGNvZWYgPSBtYXRyaXgobW0kY29lZmZpY2llbnRzLCAoMSArIG0gKyBwKSwgMSkKICB9CiAgIyBJbml0aWFsaXplcyB5aGF0IHZhcmlhYmxlcyBhbmQgTVNFCiAgeWhhdCA9IE5VTEwKICBsb3NzID0gTlVMTAogIGlmIChvcmlnIDwgblQpIHsKICAgICMgQ3JlYXRlcyBhIG5mY3N0IGJ5IChtKzIpIG1hdHJpeAogICAgIyBBZGQgb24gdGhlIGxhZ2dlZCB2YXJpYWJsZXMKICAgIG5ld3ggPSBjYmluZChyZXAoMSwgKG5UIC0gb3JpZykpLCBEaW5kZXhbKG9yaWcgKyAxKTpuVCwgXSwgYWxsX2xhZ1sob3JpZysxKTpuVCxdKQogICAgIyBJbmNvcnBvcmF0ZSBsYWdnZWQgdmFyaWFibGVzCiAgICBpZiAoYXJfdGYgPT0gMyl7CiAgICAgIG5ld3ggPSBjYmluZChyZXAoMSwgKG5UIC0gb3JpZykpLCBEaW5kZXhbKG9yaWcgKyAxKTpuVCwgXSwgYWxsX2xhZ1sob3JpZysxKTpuVCxdLCBpbmRpX21hdFsob3JpZysxKTpuVCxdKQogICAgfQogICAgIyBbbmZjc3R4KG0rMSldKlsobSsxKXgxXSA9IFtuZmNzdHgxXQogICAgeWhhdCA9IG5ld3ggJSolIGNvZWYKICAgICMgQ2FsY3VsYXRlcyBlcnJvcnMKICAgIGxvc3MgPSBhYnMoc3VtKGlmZWxzZSh5WyhvcmlnICsgMSk6blRdID4geWhhdCwgdGF1LCAoLTEpKigxLXRhdSkpKSkKICAgICMgTW9kaWZ5aW5nIHRoaXMgcGFydCB0byBvbmx5IHByaW50IHRoaXMgaWYgc3BlY2lmaWVkCiAgICBpZiAocHJpbnRfbWRsID09IDEpewogICAgICBjYXQoIkxvc3NlcyBvZiBvdXQtb2Ytc2FtcGxlIGZvcmVjYXN0czogIiwgbG9zcywgIlxuIikKICAgIH0KICB9CiAgU1dmb3JlIDwtIGxpc3QoY29lZiA9IGNvZWYsIHloYXQgPSB5aGF0LCBsb3NzID0gbG9zcywgbG9hZGluZ3MgPSBNMSwgCiAgICAgIERGaW5kZXggPSBEaW5kZXgsIG5hbWVfdmVjdG9yID0gbnZlYykKfQoKYGBgCgpgYGB7cn0KIyBEZWNpZGUgb24gdGhlIG9wdGltYWwgbnVtYmVyIG9mIHZlY3RvcnMuCgojICh5LCB4LCBvcmlnLCBtLCB0YXUpIAoKIycgRnVuY3Rpb24gdGhhdCBjYWxjdWxhdGVzIGxvc3Mgb3ZlciBhIGdpdmVuIHBlcmlvZCBvZiB0aW1lIGZvciB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsCiMnCiMnIEBwYXJhbSB5IC0gcmVzcG9uc2UgdmFyaWFibGVzCiMnIEBwYXJhbSB4IC0gZXhwbGFuYXRvcnkgdmFyaWFibGUKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIGVuZCAtIGZvcmVjYXN0aW5nIGVuZGluZy4gTm90ZTogYXMgdGhlIGZ1bmN0aW9uIGlzIGN1cnJlbnRseSB3cml0dGVuIG9uIDIvMjQsIHRoaXMgb3B0aW9uIGRvZXNuJ3QgZG8gYW55dGhpbmcuCiMnIEBwYXJhbSBtIC0gbnVtYmVyIG9mIGRpZmZ1c2lvbiBpbmRpY2VzIHRvIHVzZQojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsCiMnIEBwYXJhbSBtb2RfZGkgLSB1c2UgdGhlIG1vZGlmaWVkIERJPwojJwojJyBAcmV0dXJuIC0gcmV0dXJucyBhIGxpc3Qgb2YgdGhlIGxvc3Mgc3VtIGFuZCB0aGUgbG9zcyB2ZWN0b3IKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBsb3NzX2NhbGMocGNfZGZbLDFdLCBwY19kZlssLTFdLCA3NTcsIDEwMjcsIDEsIDAuMDEpCmxvc3NfY2FsYyA9IGZ1bmN0aW9uKHksIHgsIG9yaWcsIG0sIHRhdSwgbW9kX2RpID0gMCwgYXJfdGYgPSAxLCBwID0gMSwgcHJpbnRfbWRsID0gMCwgbW9kZWwgPSAxLCBlbmQgPSBOVUxMKXsKICAjIEV4dHJhY3QgeV9oYXQgdmFsdWVzCiAgaWYgKG1vZF9kaSA9PSAwKXsKICAgIGRpID0gbW9kX2RpKHk9eSx4PXgsb3JpZz1vcmlnLG09bSwgdGF1PXRhdSwgZW5kID0gZW5kLCBwcmludF9tZGwgPSBwcmludF9tZGwpCiAgfQogIGVsc2UgewogICAgZGkgPSBtb2RfZGlfd2woeT15LHg9eCxvcmlnPW9yaWcsbT1tLCB0YXU9dGF1LCBhcl90ZiA9IGFyX3RmLCBwID0gcCwgcHJpbnRfbWRsID0gcHJpbnRfbWRsLCBtb2RlbCA9IG1vZGVsLCBlbmQgPSBlbmQpCiAgfQogICMgbW9kX2RpX3dsID0gZnVuY3Rpb24gKHksIHgsIG9yaWcsIG0sIHRhdSwgYXJfdGYgPSAxLCBwID0gMSwgcHJpbnRfbWRsID0gMCwgbW9kZWwgPSAxKQogIHloYXQgPSBkaSR5aGF0WzE6KGVuZC1vcmlnKV0KICAjIENhbGN1bGF0ZSB0aGUgbG9zcwogICMgSW5pdGlhbGl6ZSBsb3NzIHZlY3RvcgogIGx2ZWMgPSByZXAoMCwoZW5kLW9yaWcpKQogICMgVGFrZSB0aGUgZGlmZmVyZW5jZQogIGZvciAoaSBpbiAxOihlbmQtb3JpZykpewogICAgIyBDYWxjdWxhdGUgYW4gaW5kaWNhdG9yIHZhcmlhYmxlCiAgICBpbmQgPSBpZmVsc2UoeVtvcmlnK2ldIDwgeWhhdFtpXSwgMSwwKQogICAgIyBVc2UgaW5kaWNhdG9yIGluIGZ1bmN0aW9uIGJlbG93CiAgICBsdmVjW2ldID0gKHRhdSAtIGluZCkqKHlbb3JpZytpXSAtIHloYXRbaV0pCiAgfQogICMgQWRkIHVwIHRoZSBsb3NzZXMgLSBjaGFuZ2UgdG8gbG9vayBhdCBzdW0gb2YgbG9zc2VzLiBXb24ndCBjaGFuZ2UgZGVjaXNpb24gY3JpdGVyaW9uCiAgc3VtbG9zcyA9IHN1bShsdmVjKQogICMgc3VtbG9zcyA9IHN1bShsdmVjKS9sZW5ndGgobHZlYykKICByZXR1cm4obGlzdChzdW1sb3NzLGx2ZWMpKQp9CgoKYGBgCgoKYGBge3J9CiMnIEZ1bmN0aW9uIHRoYXQgc2VsZWN0cyB0aGUgb3B0aW1hbCBudW1iZXIgb2YgcHJlZGljdG9ycwojJwojJyBAcGFyYW0geSAtIHJlc3BvbnNlIHZlY3RvcgojJyBAcGFyYW0geCAtIHByZWRpY3RvciB2YXJpYWJsZXMKIycgQHBhcmFtIG9yaWcgLSBmb3JlY2FzdCBvcmlnaW4KIycgQHBhcmFtIGVuZCAtIGVuZGluZyBvZiB2YWxpZGF0aW9uIHNldAojJyBAcGFyYW0gdGF1IC0gVmFSIGluIHF1ZXN0aW9uCiMnIEBwYXJhbSBsb3dfbSAtIGxvdyB2YWx1ZSBvZiBtIHRvIGNvbnNpZGVyCiMnIEBwYXJhbSBoaWdoX20gLSBoaWdoIHZhbHVlIG9mIG0gdG8gY29uc2lkZXIKIycKIycgQHJldHVybiAtIHJldHVybnMgdGhlIG9wdGltYWwgdmFsdWUgb2YgbQojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIG9wdF9tKHBjX2RmWywxXSwgcGNfZGZbLC0xXSwgNzU3LCAxMDI3LCAwLjAxLCBsb3dfbSA9MSwgaGlnaF9tICA9IDUpCm9wdF9tID0gZnVuY3Rpb24oeSwgeCwgb3JpZywgZW5kID0gTlVMTCwgdGF1LCBsb3dfbSA9IDEsIGhpZ2hfbSwgbW9kX2RpID0gMCwgYXJfdGYgPSAxLCBwID0gMSwgcHJpbnRfbWRsID0gMCwgbW9kZWwgPSAxLCByb3duYW1lID0gTlVMTCl7CiAgIyBJbml0aWFsaXplIGEgbG9zcyB2ZWN0b3IKICBsb3NzX3ZlYyA9IHJlcCgwLGhpZ2hfbS1sb3dfbSArIDEpCiAgIyBJbml0aWFsaXplIGFuIG0gdmVjdG9yCiAgbV92ZWMgPSBzZXEobG93X20sIGhpZ2hfbSwgYnkgPSAxKQogICMgTG9vcCB0aHJvdWdoIGFuZCBwb3B1bGF0ZSB0aGUgbG9zcyB2ZWN0b3IKICBmb3IgKGkgaW4gMTpsZW5ndGgobG9zc192ZWMpKXsKICAgIGxvc3NfdmVjW2ldID0gcXVpZXQobG9zc19jYWxjKHk9eSx4PXgsb3JpZz1vcmlnLGVuZD1lbmQsIG0gPSBtX3ZlY1tpXSwgdGF1ID0gdGF1LCBtb2RfZGkgPSBtb2RfZGksIGFyX3RmID0gYXJfdGYsIHAgPSBwLCBwcmludF9tZGwgPSBwcmludF9tZGwsIG1vZGVsID0gbW9kZWwpKVtbMV1dCiAgfQogICMgRmluZCB0aGUgbWluaW1pemVyCiAgb3B0X20gPSB3aGljaC5taW4obG9zc192ZWMpCiAgb3B0X3AgPSBOQQogICMgQ29tYmluZSBpbnRvIGEgZGF0YSBmcmFtZQogIGRmID0gYXMuZGF0YS5mcmFtZShjYmluZChvcHRfbSwgb3B0X3ApKQogIG5hbWVzKGRmKSA8LSBjKCJPcHRpbWFsIG0iLCAiT3B0aW1hbCBwIikKICAjIEFzc2lnbiBhIHJvd25hbWUKICBpZiAoaXMubnVsbChyb3duYW1lKSA9PSBUUlVFKXsKICAgICMgV3JpdGUgdGhlIHJvdyBuYW1lcwogICAgcm93bmFtZXMoZGYpIDwtIGMoIk1WIENBVmlhUiIpCiAgfQogIGVsc2UgewogICAgcm93bmFtZXMoZGYpIDwtIHJvd25hbWUKICB9CiAgIyBSZXR1cm4gdGhlIGxvc3NfdmVjdG9yIGFuZCB0aGUgbWluaW16ZXIKICByZXR1cm4obGlzdChvcHRfbSwgbG9zc192ZWMsIGRmKSkKfQpgYGAKCmBgYHtyfQojJyBGdW5jdGlvbiB0aGF0IHNlbGVjdHMgdGhlIG9wdGltYWwgbnVtYmVyIG9mIGxhZ3MKIycKIycgQHBhcmFtIHkgLSByZXNwb25zZSB2ZWN0b3IKIycgQHBhcmFtIHggLSBwcmVkaWN0b3IgdmFyaWFibGVzCiMnIEBwYXJhbSBvcmlnIC0gZm9yZWNhc3Qgb3JpZ2luCiMnIEBwYXJhbSBlbmQgLSBlbmRpbmcgb2YgdmFsaWRhdGlvbiBzZXQKIycgQHBhcmFtIHRhdSAtIFZhUiBpbiBxdWVzdGlvbgojJyBAcGFyYW0gbG93X20gLSBsb3cgdmFsdWUgb2YgbSB0byBjb25zaWRlcgojJyBAcGFyYW0gaGlnaF9tIC0gaGlnaCB2YWx1ZSBvZiBtIHRvIGNvbnNpZGVyCiMnCiMnIEByZXR1cm4gLSByZXR1cm5zIHRoZSBvcHRpbWFsIHZhbHVlIG9mIG0KIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBvcHRfbXAoeSA9IHBjX2RmWywxXSwgeCA9IHBjX2RmWywtMV0sIG9yaWcgPSA3NTcsIGVuZCA9IDEwMDcsIHRhdSA9IDAuMDEsIGxvd19tID0xLCBoaWdoX20gID0gNSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgYXJfdGYgPSAyLCBtb2RfZGkgPSAxKQpvcHRfbXAgPSBmdW5jdGlvbih5LCB4LCBvcmlnLCBlbmQgPSBOVUxMLCB0YXUsIGxvd19tID0gMSwgaGlnaF9tLCBsb3dfcCA9IDEsIGhpZ2hfcCwgbW9kX2RpID0gMCwgYXJfdGYgPSAxLCBwcmludF9tZGwgPSAwLCBtb2RlbCA9IDEsIHByaW50X21wID0gMCwgcm93bmFtZSA9IE5VTEwpewogICMgSW5pdGlhbGl6ZSBhIGxvc3MgbWF0cml4CiAgbG9zc19tYXQgPSBtYXRyaXgoMCwgaGlnaF9wLWxvd19wICsgMSxoaWdoX20tbG93X20gKyAxKQogICMgSW5pdGlhbGl6ZSBhIHAgdmVjdG9yCiAgcF92ZWMgPSBzZXEobG93X3AsIGhpZ2hfcCwgYnkgPSAxKQogICMgTG9vcCB0aHJvdWdoIGFuZCBwb3B1bGF0ZSB0aGUgbG9zcyB2ZWN0b3IKICBmb3IgKGkgaW4gMTpucm93KGxvc3NfbWF0KSl7CiAgICBsb3NzX21hdFtpLF0gPSBvcHRfbSh5ID0geSwgeCA9IHgsIG9yaWcgPSBvcmlnLCBlbmQgPSBlbmQsIHRhdSA9IHRhdSwgbG93X20gPSBsb3dfbSwgaGlnaF9tICA9IGhpZ2hfbSwgcCA9IGksIG1vZF9kaSA9IG1vZF9kaSwgYXJfdGYgPSBhcl90ZiwgcHJpbnRfbWRsID0gcHJpbnRfbWRsLCBtb2RlbCA9IG1vZGVsKVtbMl1dCiAgfQogICMgRmluZCB0aGUgbWluaW1pemVyCiAgb3B0X3AgPSB3aGljaChsb3NzX21hdCA9PSBtaW4obG9zc19tYXQpLCBhcnIuaW5kID0gVFJVRSlbMSwxXQogIG9wdF9tID0gd2hpY2gobG9zc19tYXQgPT0gbWluKGxvc3NfbWF0KSwgYXJyLmluZCA9IFRSVUUpWzEsMl0KICAjIFByaW50IHRoZSBvcHRpbWFsIHAgYW5kIG9wdGltYWwgbQogIGRmID0gYXMuZGF0YS5mcmFtZShjYmluZChvcHRfbSwgb3B0X3ApKQogIG5hbWVzKGRmKSA8LSBjKCJPcHRpbWFsIG0iLCAiT3B0aW1hbCBwIikKICAjIEFzc2lnbiBhIHJvd25hbWUKICBpZiAoaXMubnVsbChyb3duYW1lKSA9PSBUUlVFKXsKICAgIGlmIChhcl90ZiA9PSAxKXsKICAgICAgIyBXcml0ZSB0aGUgcm93IG5hbWVzCiAgICAgIHJvd25hbWVzKGRmKSA8LSBjKCJNViBDQVZpYVIgKyBBUiIpCiAgICB9IGVsc2UgaWYgKGFyX3RmID09IDIpewogICAgICAjIFdyaXRlIHRoZSByb3cgbmFtZXMKICAgICAgcm93bmFtZXMoZGYpIDwtIGMoIk1WIENBVmlhUiArIFNBViIpCiAgICB9IGVsc2UgaWYgKGFyX3RmID09IDMpewogICAgICAjIFdyaXRlIHRoZSByb3cgbmFtZXMKICAgICAgcm93bmFtZXMoZGYpIDwtIGMoIk1WIENBVmlhUiArIEFTIikKICAgIH0gZWxzZSB7CiAgICAgIHJvd25hbWVzKGRmKSA8LSBjKCJVbmtub3duIE1vZGVsIikKICAgIH0KICB9CiAgZWxzZSB7CiAgICByb3duYW1lcyhkZikgPC0gcm93bmFtZQogIH0KICAjIFByaW50IHRoZSBkZiBpZiB0aGUgb3B0aW9uIGlzIHR1cm5lZCBvbgogIGlmIChwcmludF9tcCA9PSAxKXsKICAgIHByaW50KGRmKQogIH0KICAjIFJldHVybiB0aGUgbG9zc192ZWN0b3IgYW5kIHRoZSBtaW5pbXplcgogIHJldHVybihsaXN0KG9wdF9tLCBvcHRfcCwgbG9zc19tYXQsIGRmKSkKfQpgYGAKCgpgYGB7cn0KIycgQSBmdW5jdGlvbiB0aGF0IGNvbWJpbmVzIG9wdGltYWwgdmFsdWVzIG9mIG0gYW5kIHAgaW50byBhIGZpbmFsIHRhYmxlCiMnCiMnIEBwYXJhbSBtMSAtIHRoZSBkYXRhIGZyYW1lIGZyb20gdGhlICJNViBDQVZpYVIiIHJ1bgojJyBAcGFyYW0gbTIgLSB0aGUgZGF0YSBmcmFtZSBmcm9tIHRoZSAiTVYgQ0FWaWFSICsgQVIiIHJ1bgojJyBAcGFyYW0gbTMgLSB0aGUgZGF0YSBmcmFtZSBmcm9tIHRoZSAiTVYgQ0FWaWFSICsgU0FWIiBydW4KIycgQHBhcmFtIG00IC0gdGhlIGRhdGEgZnJhbWUgZnJvbSB0aGUgIk1WIENBVmlhUiArIEFTIiBydW4KIycKIycgQHJldHVybiAtIGEgbmljZWx5IGZvcm1hdHRlZCB0YWJsZQojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcyAtIHByZXR0eV9wbShvcHRfcHJlZF9ubFtbM11dLCBvcHRfcG1fbTFbWzRdXSwgb3B0X3BtX20yW1s0XV0sIG9wdF9wbV9tM1tbNF1dKQpwcmV0dHlfcG0gPSBmdW5jdGlvbihtMSwgbTIsIG0zLCBtNCl7CiAgIyBNZXJnZSB0aGUgaW5kaXZpZHVhbCBkYXRhIGZyYW1lcwogIHBtX3ByZXR0eV9kZiA9IHJiaW5kKG0xLCBtMiwgbTMsIG00KQogICMgRm9ybWF0IG5pY2VseQogIHBtX3ByZXR0eV9kZiAlPiUga2FibGUoY2FwdGlvbiA9ICJPcHRpbWFsIE51bWJlciBvZiBEaWZmdXNpb24gSW5kaWNlcyAobSkgYW5kIExhZ3MgKHApIGZvciBEaWZmZXJlbnQgTW9kZWxzIiwgZGlnaXRzID0gMCkgJT4lIGthYmxlX3N0eWxpbmcoInN0cmlwZWQiLCBmdWxsX3dpZHRoID0gRikgJT4lIGthYmxlX3N0eWxpbmcoKSAlPiUgZm9vdG5vdGUoZ2VuZXJhbCA9ICJUaGUgTVYgQ0FWaWFSIG1vZGVsIGRvZXNuJ3QgaGF2ZSBhbiBvcHRpbWFsIHZhbHVlIGZvciBwIGJlY2F1c2UgdGhlcmUgYXJlIG5vIEFSIGxhZ3MgaW4gdGhlIG1vZGVsIgogICkKICAKfQoKYGBgCgoKYGBge3J9CiMnIEhlcmUgaXMgYSBmdW5jdGlvbiB0aGF0IHJ1bnMgdGhlIHVuaXZhcmlhdGUgQ0FWaWFSIG1vZGVsIDQgdGltZXMKIycKIycgQHBhcmFtIGRmIC0gdGhlIHBlcmNlbnQgY2hhbmdlIGRhdGEgZnJhbWUgdG8gY29uc2lkZXIKIycgQHBhcmFtIG5mY3N0IC0gbnVtYmVyIG9mIGZvcmVjYXN0cyB0byBydW4KIycgQHBhcmFtIHRhdSAtIHRoZSBWYVIgbGV2ZWwgdG8gY29uc2lkZXIKIycgQHBhcmFtIG5vX3J1biAtIHNwZWNpZmllcyBpZiBhbnkgbW9kZWxzIHNob3VsZCBub3QgYmUgcnVuCiMnCiMnIEByZXR1cm4gLSBhIGxpc3Qgb2YgdGhlIDQgdW5pdmFyaWF0ZSBtb2RlbCBmb3JlY2FzdHMKIycgQGV4cG9ydAojJwojJyBAZXhhbXBsZXMgLSBhY2VnID0gZ2VuX3V2X3Rlc3QocGNfZGYsIDEsIDAuMDUsIG5vX3J1biA9IGMoMSwxLDAsMSkpCmdlbl91dl90ZXN0ID0gZnVuY3Rpb24oZGYsIG5mY3N0LCB0YXUsIG5vX3J1biA9IGMoMCwwLDAsMCkpewogICMgbW9kZWwgdHlwZSAoMSAtIFNBViwgMiAtIEFTLCAzIC0gR0FSQ0gsIDQgLSBBREFQVElWRSkgCiAgIyBJbml0aWFsaXplIGEgbGlzdCAgCiAgb3V0X2xpc3QgPSBsaXN0KCkKICAjIFJ1biB0aGUgZm91ciBtb2RlbHMgLSBtb2RlbCAxOyBTQVYKICBpZiAobm9fcnVuWzFdID09IDApewogICAgdXZjYXZfMSA9IHJvbGxpbmdfcHJlZGljdGlvbnMoZGZbLDFdLCByYW5nZV9kYXRhID0gKDE6bGVuZ3RoKGRmWywxXSkpLCBuZmNzdCA9IG5mY3N0LCBtb2RlbCA9IDEsIEcgPSAxMCwgY29sID0gMSwgbGV2ZWwgPSB0YXUpCiAgfQogICMgQWRkIGEgZmlsbGVyIGlmIHRoZXJlJ3Mgbm8gZW50cnkKICBlbHNlIHsKICAgIHV2Y2F2XzEgPSAwCiAgfQogICMgTW9kZWwgMiAtIEFTCiAgaWYgKG5vX3J1blsyXSA9PSAwKXsKICAgIHV2Y2F2XzIgPSByb2xsaW5nX3ByZWRpY3Rpb25zKGRmWywxXSwgcmFuZ2VfZGF0YSA9ICgxOmxlbmd0aChkZlssMV0pKSwgbmZjc3QgPSBuZmNzdCwgbW9kZWwgPSAyLCBHID0gMTAsIGNvbCA9IDEsIGxldmVsID0gdGF1KQogIH0KICBlbHNlIHsKICAgIHV2Y2F2XzIgPSAwCiAgfQogICMgTW9kZWwgMyAtIEdBUkNICiAgaWYgKG5vX3J1blszXSA9PSAwKXsKICAgIHV2Y2F2XzMgPSByb2xsaW5nX3ByZWRpY3Rpb25zKGRmWywxXSwgcmFuZ2VfZGF0YSA9ICgxOmxlbmd0aChkZlssMV0pKSwgbmZjc3QgPSBuZmNzdCwgbW9kZWwgPSAzLCBHID0gMTAsIGNvbCA9IDEsIGxldmVsID0gdGF1KQogIH0KICBlbHNlIHsKICAgIHV2Y2F2XzMgPSAwCiAgfQogICMgTW9kZWwgNCAtIEFkYXB0aXZlCiAgaWYgKG5vX3J1bls0XSA9PSAwKXsKICAgIHV2Y2F2XzQgPSByb2xsaW5nX3ByZWRpY3Rpb25zKGRmWywxXSwgcmFuZ2VfZGF0YSA9ICgxOmxlbmd0aChkZlssMV0pKSwgbmZjc3QgPSBuZmNzdCwgbW9kZWwgPSA0LCBHID0gMTAsIGNvbCA9IDEsIGxldmVsID0gdGF1KQogIH0KICBlbHNlIHsKICAgIHV2Y2F2XzQgPSAwCiAgfQogICMgRXhwb3J0IHRoZSBkYXRhIGFzIGEgbGlzdAogIHJldHVybihsaXN0KHV2Y2F2XzEsIHV2Y2F2XzIsIHV2Y2F2XzMsIHV2Y2F2XzQpKQp9CgpgYGAKCmBgYHtyfQojJyBGdW5jdGlvbiB0byBwbG90IHRoZSBkYXRhIHdoaWNoIHdlIGdlbmVyYXRlIGluIHByZXZpb3VzIGZ1bmN0aW9ucwojJwojJyBAcGFyYW0gcGxvdF9tYXRyaXggLSBtYXRyaXggd2l0aCB0aGUgZGF0YSB0byBwbG90CiMnIEBwYXJhbSBub3JtX3ZhbHVlIC0gd2hhdCB0byBzdWJ0YWN0IGZyb20gdGhlIGRhdGEgdG8gbWFrZSBpdCBvbiBhIHBlcmNlbnRhZ2UgY2hhbmdlIGJhc2lzLiBEZWZhdWx0IGlzIDEwMC4KIycKIycgQHJldHVybiAKIycgQGV4cG9ydCAtIGEgcGxvdCBvZiB0aGUgZGF0YSBieSBkaWZmdXNpb24gaW5kZXggbnVtYmVyCiMnCiMnIEBleGFtcGxlcyA9IHBsdF9kYXRhKHBsb3RfbXR4W1sxXV0pLCBhYmMgPSBwbHRfZGF0YShwbG90X21hdCwgdGF1ID0gMC4wMSkKcGx0X2RhdGEgPSBmdW5jdGlvbihwbG90X21hdHJpeCwgdGF1LCByZXNwX3ZhciwgbnRlc3QpewogICMgRXN0YWJsaXNoIGEgbWF4aW11bSBhbmQgbWluaW11bSB2YWx1ZQogIG1heF92YWwgPSBtYXgocGxvdF9tYXRyaXhbLDE6bmNvbChwbG90X21hdHJpeCldKQogIG1pbl92YWwgPSBtaW4ocGxvdF9tYXRyaXhbLDE6bmNvbChwbG90X21hdHJpeCldKQogICMgQ2FsY3VsYXRlIGluaXRhbCBhbmQgZW5kaW5nIHRpbWUgdmFsdWUKICBzdGFydCA9IGluZGV4KHBsb3RfbWF0cml4KVsxXQogIGVuZCA9IGluZGV4KHBsb3RfbWF0cml4KVtucm93KHBsb3RfbWF0cml4KV0KICBpbmRfdmFscyA9IGluZGV4KHBsb3RfbWF0cml4KSAtIHN0YXJ0CiAgIyBDcmVhdGUgYW4gaW5pdGlhbCBwbG90IGFuZCBhZGQgbGluZXMKICAgIGZvciAoaSBpbiAxOm5jb2wocGxvdF9tYXRyaXgpKXsKICAgICAgaWYgKGkgPT0gMSl7CiAgICAgICAgIyA0LzIvMjAyMCAtIGZpeGluZyB0aGUgaW5kZXgKICAgICAgICBwbG90LnRzKGluZF92YWxzLHBsb3RfbWF0cml4WyxpXSwgdHlwZSA9ICJsIiwgeGxhYiA9IHBhc3RlKCJEYXlzIFNpbmNlIiwgYXMuRGF0ZShzdGFydCkpLCB5bGFiID0gIlBlcmNlbnQgQ2hhbmdlIGluIFBHIiwgeWxpbSA9IGMobWluX3ZhbCxtYXhfdmFsKSwgbHdkID0gMSwgbWFpbiA9IHBhc3RlKCJQcmVkaWN0aW5nIiwgcmVzcF92YXIsICJSZXR1cm5zIGZyb20iLCBhcy5EYXRlKHN0YXJ0KSwgInRvIiwgYXMuRGF0ZShlbmQpKSwgc3ViID0gcGFzdGUoIlRoZSBWYVIgTGV2ZWwgaXMgIiwgMTAwKnRhdSwgIiUiLCAiOyBUaGVyZSBhcmUgIiwgbnRlc3QsICIgVHJhZGluZyBEYXlzIFBsb3R0ZWQgQWJvdmUiLCBzZXAgPSAiIikpCiAgICAgICAgIyBwbG90LnRzKGluZGV4KHBsb3RfbWF0cml4KSwgcGxvdF9tYXRyaXhbLGldLCB0eXBlID0gImwiLCB4bGFiID0gIlRyYWRpbmcgRGF5cyIsIHlsYWIgPSAiUGVyY2VudCBDaGFuZ2UgaW4gUEciLCB5bGltID0gYyhtaW5fdmFsLG1heF92YWwpLCBsd2QgPSAxLCBtYWluID0gIlByZWRpY3RpbmcgUEcgUmV0dXJucyBPdmVyIExhc3QgMjUwIFRyYWRpbmcgRGF5cyBpbiAyMDA4Iiwgc3ViID0gcGFzdGUoIlRoZSBWYVIgTGV2ZWwgaXMgIiwgMTAwKnRhdSwgIiUiLCBzZXAgPSAiIikpCiAgICB9IGVsc2UgaWYoaSAlaW4lIHNlcSgyLDgsMSkpIHsKICAgICAgICBsaW5lcyhpbmRfdmFscyxwbG90X21hdHJpeFssaV0sIGNvbCA9IGktMSwgbHR5ID0gMikKICAgIH0gZWxzZSB7CiAgICAgICAgbGluZXMoaW5kX3ZhbHMscGxvdF9tYXRyaXhbLGldLCBjb2wgPSBpLTEsIGx0eSA9IDIsIGx3ZCA9IDIpCiAgICB9CiAgICB9CiAgIyBEZWZpbmUgYSBzZXF1ZW5jZSBmb3IgcGxvdHRpbmcKICBwbG90X3NlcSA9IHNlcSgxLCBuY29sKHBsb3RfbWF0cml4KSkKICBsZWdlbmQoInRvcGxlZnQiLCBsZWdlbmQgPSBjKGNvbG5hbWVzKHBsb3RfbWF0cml4KSksIGNvbCA9IHBsb3Rfc2VxLCBsdHkgPSBjKDEsIHJlcCgyLCA3KSwgcmVwKDMsIGlmZWxzZShuY29sKHBsb3RfbWF0cml4KS04IDw9IDAsIDAsIG5jb2wocGxvdF9tYXRyaXgpLTgpKSksIGx3ZCA9IGMoMSwgcmVwKDEsIDcpLCByZXAoMiwgaWZlbHNlKG5jb2wocGxvdF9tYXRyaXgpLTggPD0gMCwgMCwgbmNvbChwbG90X21hdHJpeCktOCkpKSkKICAjIEFkZCBhIGxpbmUgZm9yIDAKICAjIGFibGluZShoID0gMCwgY29sID0gImJsYWNrIiwgbHR5ID0gMikKfQoKCmBgYAoKYGBge3J9CiMnIEEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGxvc3NlcyBiYXNlZCBvbiB0aGUgdGVzdCBzYW1wbGUKIycKIycgQHBhcmFtIHRydWVfdmVjIC0gdGhlIHRydWUgdmVjdG9yIG9mIHJldHVybnMKIycgQHBhcmFtIHByZWRfdmVjIC0gdGhlIHByZWRpY3RlZCB2ZWN0b3IgZnJvbSB0aGUgbW9kZWwgcnVucwojJyBAcGFyYW0gdGF1IC0gVmFSIGxldmVsLiBNdXN0IG1hdGNoIHdoYXQgdGhlIG1vZGVsIHVzZWQKIycKIycgQHJldHVybiAtIHRvdGFsIGxvc3NlcyBhbmQgdGhlIGVudGlyZSBsb3NzIHZlY3RvcgojJyBAZXhwb3J0CiMnCiMnIEBleGFtcGxlcwpsb3NzX3Rlc3QgPSBmdW5jdGlvbih0cnVlX3ZlYywgcHJlZF92ZWMsIHRhdSl7CiAgIyBJbml0aWFsaXplIGEgbG9zcyB2ZWN0b3IKICBsdmVjID0gcmVwKDAsIGxlbmd0aCh0cnVlX3ZlYykpCiAgIyBJbml0aWFsaXplIGEgYnJlYWsgdmVjdG9yIHRvIHNlZSB3aGVuIFZhUiBpcyBicm9rZW4KICBidmVjID0gcmVwKDAsIGxlbmd0aCh0cnVlX3ZlYykpCiAgZm9yIChpIGluIDE6bGVuZ3RoKHRydWVfdmVjKSl7CiAgICAjIENhbGN1bGF0ZSBhbiBpbmRpY2F0b3IgdmFyaWFibGUKICAgIGJ2ZWNbaV0gPSBpZmVsc2UodHJ1ZV92ZWNbaV0gPCBwcmVkX3ZlY1tpXSwgMSwwKQogICAgIyBVc2UgaW5kaWNhdG9yIGluIGZ1bmN0aW9uIGJlbG93CiAgICBsdmVjW2ldID0gKHRhdSAtIGJ2ZWNbaV0pKih0cnVlX3ZlY1tpXSAtIHByZWRfdmVjW2ldKQogIH0KICAjIEFkZCB1cCB0aGUgbG9zc2VzCiAgIyBzdW1sb3NzID0gc3VtKGx2ZWMpL2xlbmd0aChsdmVjKQogIHN1bWxvc3MgPSBzdW0obHZlYykKICAjIEFkZCB1cCB0aGUgVmFSIGJyZWFrYWdlCiAgdmFyYnJlYWsgPSBzdW0oYnZlYykvbGVuZ3RoKGJ2ZWMpCiAgcmV0dXJuKGxpc3Qoc3VtbG9zcyxsdmVjLCB2YXJicmVhaywgYnZlYykpCn0KYGBgCgoKCmBgYHtyfQojJyBBIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBsb3NzZXMgYmFzZWQgb24gdGhlIHBsb3QgbWF0cml4CiMnCiMnIEBwYXJhbSBkYXRhX21hdCAtIGEgbWF0cml4IG9mIGZvcmVjYXN0ZWQgVmFSIHZhbHVlcywgd2l0aCB0aGUgdHJ1ZSB2YWx1ZSBpbiB0aGUgZmlyc3QgY29sdW1uCiMnIEBwYXJhbSB0YXUgLSBWYVIgbGV2ZWwuIE11c3QgbWF0Y2ggd2hhdCB0aGUgbW9kZWwgdXNlZAojJwojJyBAcmV0dXJuIC0gYSBsaXN0IG9mIGZvdXIgaXRlbXMuIAojJyAxID0gYSB2ZWN0b3Igb2YgdGhlIGxvc3NlcyBvZiBhbGwgbW9kZWxzLiAKIycgMiA9IGEgdmVjdG9yIHNob3dpbmcgdGhlIHBlcmNlbnRhZ2Ugb2YgVmFSIGJyZWFrcyBieSBtb2RlbAojJyAzID0gdGhlIGxvc3MgbWF0cml4CiMnIDQgPSB0aGUgYnJlYWsgbWF0cml4CiMnIEBleHBvcnQKIycKIycgQGV4YW1wbGVzCmdlbl9sb3NzX3Rlc3QgPSBmdW5jdGlvbihkYXRhX21hdCwgdGF1KXsKICAjIEluaXRpYWxpemUgbG9zcyBhbmQgYnJlYWsgbWF0cmljZXMKICBsbWF0ID0gYm1hdCA9IG1hdHJpeCgwLCBucm93ID0gbnJvdyhkYXRhX21hdCksIG5jb2wgPSBuY29sKGRhdGFfbWF0KS0xKQogICMgYnZlYyA9IHJlcCgwLCBsZW5ndGgodHJ1ZV92ZWMpKQogICMgUG9wdWxhdGUgdGhlIG1hdHJpY2VzCiAgZm9yIChpIGluIDE6bnJvdyhsbWF0KSl7CiAgICBmb3IgKGogaW4gMToobmNvbChsbWF0KSkpewogICAgICAjIENhbGN1bGF0ZSBhbiBpbmRpY2F0b3IgdmFyaWFibGUKICAgICAgYm1hdFtpLGpdID0gaWZlbHNlKGRhdGFfbWF0W2ksMV0gPCBkYXRhX21hdFtpLGorMV0sIDEsMCkKICAgICAgIyBVc2UgaW5kaWNhdG9yIGluIGZ1bmN0aW9uIGJlbG93CiAgICAgIGxtYXRbaSxqXSA9ICh0YXUgLSBibWF0W2ksal0pKihkYXRhX21hdFtpLDFdIC0gZGF0YV9tYXRbaSxqKzFdKQogICAgfSAgICAKICB9CiAgIyBBZGQgdXAgdGhlIGxvc3NlcwogIHN1bWxvc3MgPSBjb2xTdW1zKGxtYXQpCiAgIyBBZGQgdXAgdGhlIFZhUiBicmVha2FnZQogIHZhcmJyZWFrID0gY29sU3VtcyhibWF0KS9ucm93KGJtYXQpCiAgcmV0dXJuKGxpc3Qoc3VtbG9zcywgdmFyYnJlYWssIGxtYXQsIGJtYXQpKQp9CmBgYAoKCgpgYGB7cn0KIycgQSBmdW5jdGlvbiB0byBtYWtlIGEgbmljZSBjb21wYXJpc29uIG9mIGxvc3NlcwojJwojJyBAcGFyYW0gZGF0YV9tYXQgLSBpbnB1dCBkYXRhIG1hdHJpeCB1c2VkIGluIHRoZSBjYWxjdWxhdGlvbiBvZiBsb3NzZXMKIycgQHBhcmFtIGxvc3NfbGlzdCAtIGEgbGlzdCBvZiB0aGUgbG9zc2VzIGNhbGN1bGF0ZWQgZnJvbSB0aGUgQ0FWaWFSIGZ1bmN0aW9uCiMnIEBwYXJhbSB0YXUgLSB0aGUgcmlzayBsZXZlbCB1c2VkCiMnIEBwYXJhbSBudGVzdCAtIHRoZSBudW1iZXIgb2YgdGVzdCBwb2ludHMKIycKIycgQHJldHVybgojJyBAZXhwb3J0IC0gcmV0dXJucyBhIG5pY2VseSBmb3JtYXR0ZWQgdGFibGUKIycKIycgQGV4YW1wbGVzIC0gcHJldHR5X3RhYmxlcyhwbG90X21hdCwgbF9saXN0LCB0YXUgPSAwLjAxKQpwcmV0dHlfdGFibGVzID0gZnVuY3Rpb24oZGF0YV9tYXQsIGxvc3NfbGlzdCwgdGF1LCBudGVzdCl7CiAgIyBDb21iaW5lIGludG8gYSBkYXRhIGZyYW1lCiAgZGYgPSBhcy5kYXRhLmZyYW1lKHJiaW5kKGxvc3NfbGlzdFtbMV1dLCBsb3NzX2xpc3RbWzJdXSkpCiAgIyBDYWxjdWxhdGUgaW5pdGFsIGFuZCBlbmRpbmcgdGltZSB2YWx1ZQogIHN0YXJ0ID0gaW5kZXgoZGF0YV9tYXQpWzFdCiAgZW5kID0gaW5kZXgoZGF0YV9tYXQpW25yb3coZGF0YV9tYXQpXQogICMgQWRkIHJvdy9jb2x1bW4gbmFtZXMKICBjb2xuYW1lcyhkZikgPC0gY29sbmFtZXMoZGF0YV9tYXRbLC0xXSkKICByb3duYW1lcyhkZikgPC0gYygiTG9zc2VzIiwgIlZhUiBCcmVha3MgKCUpIikKICAjIENvbnZlcnQgdG8gYSB0YWJsZQogIGRmICU+JSBrYWJsZShjYXB0aW9uID0gcGFzdGUoIkNvbXBhcmlzb24gb2YgVmFSIE1ldGhvZHMgZm9yIGEgIiwgdGF1KjEwMCwgIiUgVmFSIiwgc2VwID0gIiIpLCBkaWdpdHMgPSAzKSAlPiUga2FibGVfc3R5bGluZygic3RyaXBlZCIsIGZ1bGxfd2lkdGggPSBGKSAlPiUga2FibGVfc3R5bGluZygpICU+JSBmb290bm90ZShnZW5lcmFsID0gcGFzdGUoIkNhbGN1bGF0ZWQgdXNpbmciLCBudGVzdCwgInRyYWRpbmcgZGF5cyBmcm9tIiwgYXMuRGF0ZShzdGFydCksICJ0byIsIGFzLkRhdGUoZW5kKSkpCn0KYGBgCgpgYGB7cn0KIycgQSBkcmVzc2VkIHVwIHZlcnNpb24gb2YgdGhlIGV4cG9ydCBmdW5jdGlvbgojJwojJyBAcGFyYW0gdmFyX2ZpbGUgLSBmaWxlIHRvIGV4cG9ydAojJyBAcGFyYW0gcGF0aCAtIGZpbGVwYXRoCiMnIEBwYXJhbSBmaWxlbmFtZSAtIG5hbWUgb2YgdGhlIGZpbGUsIGVuZGluZyB3aXRoIC5DU1YKIycKIycgQHJldHVybgojJyBAZXhwb3J0IC0gZXhwb3J0ZWQgQ1NWIGZpbGUKIycKIycgQGV4YW1wbGVzIC0gZXhwX2Z1bmModmFyX2ZpbGUgPSB2YXJfMXBjXzIwMTZfdXNldGZbWzFdXSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gIlRFU1QuY3N2IikKZXhwX2Z1bmMgPSBmdW5jdGlvbih2YXJfZmlsZSwgcGF0aCwgZmlsZW5hbWUpewogICMgV3JpdGUgYSB6b28KICB3cml0ZS56b28odmFyX2ZpbGUsIHBhc3RlMChwYXRoLCBmaWxlbmFtZSksIHF1b3RlID0gRkFMU0UsIHNlcCA9ICIsIikKfQoKIyBleHBfZnVuYyh2YXJfZmlsZSA9IHZhcl8xcGNfMjAxNl91c2V0ZltbMV1dLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAiVEVTVC5jc3YiKQoKYGBgCgoKCgojIEJpZyBTaW11bGF0aW9uIEZ1bmN0aW9uCgpgYGB7cn0KIycgVGhpcyBpcyB0aGUgIm1hc3RlciIgZnVuY3Rpb24gd2hlcmUgd2UnbGwgZXZhbHVhdGUgdGhlIGltcG9ydGFuY2Ugb2YgdGhlIFZhUiBtb2RlbCBvdmVyIHNldmVyYWwgdGltZSBwZXJpb2RzCiMnCiMnIEBwYXJhbSBzeW1ib2xfbGlzdCAtIGEgbGlzdCBvZiBzeW1ib2xzIHRvIGZlZWQgaW50byB0aGUgbW9kZWwgCiMnIEBwYXJhbSByZXNwX3ZhciAtIHRoZSByZXNwb25zZSB2YXJpYWJsZQojJyBAcGFyYW0gY29tcGxfY2FzZSAtIHNob3VsZCB0aGUgbW9kZWwgcmVxdWlyZSBjb21wbGV0ZSBjYXNlcz8gRGVmYXVsdCB2YWx1ZSBpcyAxLgojJyBAcGFyYW0gYWRqX2Nsb3NlIC0gdXNlIGFkanVzdGVkIGNsb3NlIHByaWNlIGZvciB0aGUgcHJlZGljdG9ycz8gRGVmYXVsdCB2YWx1ZSBpcyAxLgojJyBAcGFyYW0gcmVzcF9hZGpfY2xvc2UgLSB1c2UgYWRqdXN0ZWQgY2xvc2UgcHJpY2UgZm9yIHRoZSByZXNwb25zZT8gRGVmYXVsdCB2YWx1ZSBpcyAxLgojJyBAcGFyYW0gc3RhcnRfZGF0ZSAtIHN0YXJ0IGRhdGUgdG8gcHVsbCBkYXRhIGZyb20KIycgQHBhcmFtIGVuZF9kYXRlIC0gZW5kIGRhdGUgdG8gcHVsbCBkYXRhIGZyb20KIycgQHBhcmFtIG52YWwgLSBudW1iZXIgb2YgdmFsaWRhdGlvbiBwb2ludHMgdG8gdXNlCiMnIEBwYXJhbSBudGVzdCAtIG51bWJlciBvZiB0ZXN0IHBvaW50cyB0byB1c2UKIycgQHBhcmFtIHRhdSAtIFZhUiBsZXZlbCB0byB1c2UKIycgQHBhcmFtIGxvd19tIC0gbG93IG51bWJlciBvZiBwcmVkaWN0b3JzIHRvIHRlc3QKIycgQHBhcmFtIGhpZ2hfbSAgLSBsb3cgbnVtYmVyIG9mIHByZWRpY3RvcnMgdG8gdGVzdAojJyBAcGFyYW0gdXZfbGlzdCAtIGEgbGlzdCBvZiBhIHByZS1ydW4gdW5pdmFyaWF0ZSBtb2RlbC4gSWYgYSBkYXRhIGZyYW1lIGlzIG5vdCBwcm92aWRlZCwgdGhlIGxlbmd0aHkgdXYgbW9kZWwgd2lsbCBydW4gCiMnIEBwYXJhbSBub19ydW4gLSB0aGluZ3Mgbm90IHRvIHJ1biBpbiB0aGUgbW9kZWwKIycgQHBhcmFtIGxvd19wIC0gbG93IHZhbHVlIGZvciBudW1iZXIgb2YgbGFncwojJyBAcGFyYW0gaGlnaF9wIC0gaGlnaCB2YWx1ZSBmb3IgbnVtYmVyIG9mIGxhZ3MKIycgQHBhcmFtIG5hX2ludGVycCAtIHNob3VsZCB0aGUgZnVuY3Rpb24gaW50ZXJwb2xhdGUgTkEncwojJyBAcGFyYW0gcHJpbnRfbWRsIC0gcHJpbnQgdGhlIG1vZGVsIHN1bW1hcmllcz8KIycgQHBhcmFtIHByaW50X21wIC0gcHJpbnQgdGhlIG9wdGltYWwgdmFsdWVzIGZvciBwIGFuZCBtCiMnIEBwYXJhbSBsYWdfcHJlZCAtIGRvIHlvdSB3YW50IHRvIGxhZyB0aGUgbSBwcmVkaWN0b3JzIChkZWZhdWx0IGlzIDE7IHN0cm9uZ2x5IHJlY29tbWVuZGVkKQojJyBAcGFyYW0gcm93bmFtZSAtIHdoYXQgdG8gbmFtZSB0aGUgcm93cyBvZiB0aGUgbmljZSBwIGFuZCBtIG1hdHJpeAojJyBAcGFyYW0gZXhwb3J0X2NzdiAtIGRvIHlvdSB3YW50IHRvIGV4cG9ydCBhIENTVj8gRGVmYXVsdCBpcyAxLgojJyBAcGFyYW0gcGF0aCAtIHBhdGggdG8gZXhwb3J0IHRoZSBDU1YKIycgQHBhcmFtIGZpbGVuYW1lIC0gd2hhdCB0byBuYW1lIHRoZSBDU1YKIycKIycgQHJldHVybiAtIGEgbGlzdCBvZiB0aGUgcGxvdCBtYXRyaXgsIGEgcGxvdCwgYSBsaXN0IHdpdGggbG9zc2VzLCBhbmQgYSB0YWJsZQojJyBAZXhwb3J0IC0gYSBwbG90IGFuZCBhIHRhYmxlCiMnCiMnIEBleGFtcGxlcyAtIGNhdl9zaW11bChjKCJESVMiLCAiR0UiLCAiSUJNIiwgIk1NTSIsICJYT00iKSwgcmVzcF92YXIgPSAiUEciLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNSwgdGF1ID0gMC4wMSwgdXZfbGlzdCA9IHV2X2Nhdl9saXN0KQpjYXZfc2ltdWwgPSBmdW5jdGlvbihzeW1ib2xfbGlzdCwgcmVzcF92YXIsIGNvbXBsX2Nhc2UgPSAxLCBhZGpfY2xvc2UgPSAxLCByZXNwX2Fkal9jbG9zZSA9IDEsIHN0YXJ0X2RhdGUgPSAiMTkwMC0wMS0wMSIsIGVuZF9kYXRlID0gU3lzLkRhdGUoKSwgbnZhbCwgbnRlc3QsIHRhdSwgbG93X20gPSAxLCBoaWdoX20sIGxvd19wID0gMSwgaGlnaF9wLCB1dl9saXN0ID0gTlVMTCwgbm9fcnVuID0gYygwLDAsMCwwKSwgbmFfaW50ZXJwID0gVFJVRSwgcHJpbnRfbWRsID0gMCwgcHJpbnRfbXAgPSAwLCBsYWdfcHJlZCA9IDEsIHJvd25hbWUgPSBOVUxMLCBleHBvcnRfY3N2ID0gMSwgcGF0aCwgZmlsZW5hbWUpewogICMgU2VsZWN0IGRhdGEgcGFyYW1ldGVycywgcHVsbCB0aGUgZGF0YSwgYW5kIHBlcmNlbnQgY2hhbmdlIHRoZSBkYXRhCiAgZGYgPSBkaWZmX2luZGV4X2RmKHN5bWJvbF9saXN0ID0gc3ltYm9sX2xpc3QsIHJlc3BfdmFyID0gcmVzcF92YXIsIGNvbXBsX2Nhc2UgPSBjb21wbF9jYXNlLCBhZGpfY2xvc2UgPSBhZGpfY2xvc2UsIHJlc3BfYWRqX2Nsb3NlID0gcmVzcF9hZGpfY2xvc2UsIHN0YXJ0X2RhdGUgPSBzdGFydF9kYXRlLCBlbmRfZGF0ZSA9IGVuZF9kYXRlLCBsYWdfcHJlZCA9IGxhZ19wcmVkKQogICMgVGFrZSB0aGUgcGVyY2VudCBjaGFuZ2Ugb2YgdGhlIGRhdGEKICBwY19kZiA9IHBjX2RpZmZfaW5kZXgoZGYpCiAgIyBFeHRyYWN0IHRoZSBsZWdudGggb2YgdGhlIGRhdGEgZnJhbWUKICBuciA9IHRlc3RfZW5kID0gbnJvdyhwY19kZikKICAjIENhbGN1bGF0ZSB0aGUgc3RhcnQgb2YgdGhlIHZhbCBwZXJpb2QsIHRoZSBlbmQgb2YgdGhlIHZhbCBwZXJpb2QsIGFuZCB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgdGVzdCBwZXJpb2QKICB0ZXN0X29yaWcgPSB0ZXN0X2VuZCAtIG50ZXN0CiAgdmFsX2VuZCA9IHRlc3Rfb3JpZwogIHZhbF9vcmlnID0gdGVzdF9vcmlnIC0gbnZhbAogICMgVGVzdCBmb3IgdGhlIG9wdGltYWwgbnVtYmVyIG9mIHBhcmFtZXRlcnMKICBvcHRfcHJlZF9ubCA9IG9wdF9tKHkgPSBwY19kZlssMV0sIHggPSBwY19kZlssLTFdLCBvcmlnID0gdmFsX29yaWcsIGVuZCA9IHZhbF9lbmQsIHRhdSA9IHRhdSwgbG93X20gPSBsb3dfbSwgaGlnaF9tID0gaGlnaF9tLCByb3duYW1lID0gcm93bmFtZSkKICBvcHRfcHJlZF9hcnQxID0gb3B0X21wKHkgPSBwY19kZlssMV0sIHggPSBwY19kZlssLTFdLCBvcmlnID0gdmFsX29yaWcsIGVuZCA9IHZhbF9lbmQsIHRhdSA9IHRhdSwgbG93X20gPSBsb3dfbSwgaGlnaF9tID0gaGlnaF9tLCBsb3dfcCA9IGxvd19wLCBoaWdoX3AgPSBoaWdoX3AsbW9kX2RpID0gMSwgYXJfdGYgPSAxLCBwcmludF9tZGwgPSBwcmludF9tZGwsIHByaW50X21wID0gcHJpbnRfbXAsIHJvd25hbWUgPSByb3duYW1lKQogIG9wdF9wcmVkX2FydDIgPSBvcHRfbXAoeSA9IHBjX2RmWywxXSwgeCA9IHBjX2RmWywtMV0sIG9yaWcgPSB2YWxfb3JpZywgZW5kID0gdmFsX2VuZCwgdGF1ID0gdGF1LCBsb3dfbSA9IGxvd19tLCBoaWdoX20gPSBoaWdoX20sIGxvd19wID0gbG93X3AsIGhpZ2hfcCA9IGhpZ2hfcCxtb2RfZGkgPSAxLCBhcl90ZiA9IDIsIHByaW50X21kbCA9IHByaW50X21kbCwgcHJpbnRfbXAgPSBwcmludF9tcCwgcm93bmFtZSA9IHJvd25hbWUpCiAgb3B0X3ByZWRfYXJ0MyA9IG9wdF9tcCh5ID0gcGNfZGZbLDFdLCB4ID0gcGNfZGZbLC0xXSwgb3JpZyA9IHZhbF9vcmlnLCBlbmQgPSB2YWxfZW5kLCB0YXUgPSB0YXUsIGxvd19tID0gbG93X20sIGhpZ2hfbSA9IGhpZ2hfbSwgbG93X3AgPSBsb3dfcCwgaGlnaF9wID0gaGlnaF9wLCBtb2RfZGkgPSAxLCBhcl90ZiA9IDMsIHByaW50X21kbCA9IHByaW50X21kbCwgcHJpbnRfbXAgPSBwcmludF9tcCwgcm93bmFtZSA9IHJvd25hbWUpCiAgIyBnZW5fdXZfdGVzdChwY19kZiwgMSwgMC4wNSwgbm9fcnVuID0gYygxLDEsMCwxKSkKICAjIFVzZSB0aGUgYWJvdmUgZm9yZWNhc3RzIHRvIGlucHV0IGludG8gdGhlIGFib3ZlCiAgbXZfZmNzdCA9IG1vZF9kaShwY19kZlssMV0sIHBjX2RmWywtMV0sIG9yaWcgPSB0ZXN0X29yaWcsIG0gPSBvcHRfcHJlZF9ubFtbMV1dLCB0YXUgPSB0YXUsIHByaW50X21kbCA9IHByaW50X21kbCkKICBtdl9mY3N0X2FydDEgPSBtb2RfZGlfd2wocGNfZGZbLDFdLCBwY19kZlssLTFdLCBvcmlnID0gdGVzdF9vcmlnLCBtID0gb3B0X3ByZWRfYXJ0MVtbMV1dLCBwID0gb3B0X3ByZWRfYXJ0MVtbMl1dLCB0YXUgPSB0YXUsIGFyX3RmID0gMSwgcHJpbnRfbWRsID0gcHJpbnRfbWRsKQogIG12X2Zjc3RfYXJ0MiA9IG1vZF9kaV93bChwY19kZlssMV0sIHBjX2RmWywtMV0sIG9yaWcgPSB0ZXN0X29yaWcsIG0gPSBvcHRfcHJlZF9hcnQyW1sxXV0sIHAgPSBvcHRfcHJlZF9hcnQyW1syXV0sIHRhdSA9IHRhdSwgYXJfdGYgPSAyLCBwcmludF9tZGwgPSBwcmludF9tZGwpCiAgbXZfZmNzdF9hcnQzID0gbW9kX2RpX3dsKHBjX2RmWywxXSwgcGNfZGZbLC0xXSwgb3JpZyA9IHRlc3Rfb3JpZywgbSA9IG9wdF9wcmVkX2FydDNbWzFdXSwgcCA9IG9wdF9wcmVkX2FydDNbWzJdXSwgdGF1ID0gdGF1LCBhcl90ZiA9IDMsIHByaW50X21kbCA9IHByaW50X21kbCkKICAjIENhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIHByZWRpY3Rpb25zCiAgaWYgKGlzLm51bGwodXZfbGlzdCkgPT0gVFJVRSl7CiAgICAjIFByaW50IGEgd2FybmluZwogICAgcHJpbnQoIldBUk5JTkc6IE5vdCBzdXBwbHlpbmcgYW4gaW5wdXQgZGF0YSBmcmFtZSB3aWxsIHJlcXVpcmUgdGhpcyBmdW5jdGlvbiB0byBydW4gZm9yIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIHRpbWUgKDFocispIikKICAgICMgQ2FsbCB0aGUgZnVuY3Rpb24KICAgICMgZ2VuX3V2X3Rlc3QgPSBmdW5jdGlvbihkZiwgbmZjc3QsIHRhdSwgbm9fcnVuID0gYygwLDAsMCwwKSl7CiAgICAjIHByaW50KGhlYWQocGNfZGYpKQogICAgdXZfbGlzdCA9IGdlbl91dl90ZXN0KGRmID0gcGNfZGYsIG5mY3N0ID0gbnRlc3QsIHRhdSA9IHRhdSwgbm9fcnVuID0gbm9fcnVuKQogICAgIyBBZGQgdG8gYSBkYXRhIGZyYW1lCiAgICAjIEluY29ycG9yYXRlIHRoZSByb2xsaW5nIHByZWRpY3Rpb25zIGZ1bmN0aW9uIHJlc3VsdHMgaGVyZQogIHBsb3RfbWF0ID0gY2JpbmQocGNfZGZbKHRlc3Rfb3JpZysxKTpucm93KHBjX2RmKSwxXSwgbXZfZmNzdCR5aGF0WzE6bnRlc3RdLCBtdl9mY3N0X2FydDEkeWhhdFsxOm50ZXN0XSwgbXZfZmNzdF9hcnQyJHloYXRbMTpudGVzdF0sIG12X2Zjc3RfYXJ0MyR5aGF0WzE6bnRlc3RdLCB1dl9saXN0W1sxXV1bKHRlc3Rfb3JpZysxKTp0ZXN0X2VuZF0qKC0xKSwgdXZfbGlzdFtbMl1dWyh0ZXN0X29yaWcrMSk6dGVzdF9lbmRdKigtMSksIHV2X2xpc3RbWzNdXVsodGVzdF9vcmlnKzEpOnRlc3RfZW5kXSooLTEpLCB1dl9saXN0W1s0XV1bKHRlc3Rfb3JpZysxKTp0ZXN0X2VuZF0qKC0xKSkKICB9IGVsc2UgewogICAgIyBBc3NpZ24gdGhlIGNvbHVtbnMgb2YgdGhlIGRhdGEgZnJhbWUKICAgICMgaGVhZCh2YXJfNXBjXzIwMTBfdXNldGZbWzFdXVssNjo5XSkKICAgICMgbW9kZWwgdHlwZSAoMSAtIFNBViwgMiAtIEFTLCAzIC0gR0FSQ0gsIDQgLSBBREFQVElWRSkgCiAgICAjIHRlc3RfZGYgPSBoZWFkKHZhcl81cGNfMjAxMF91c2V0ZltbMV1dWyw2OjldKQogICAgIyB0ZXN0X2RmJFNBVgogICAgIyB0ZXN0X2RmJGBBYnMuIFNsb3BlYAogICAgIyB0ZXN0X2RmJGBJbmQuIEdBUkNIYAogICAgIyB0ZXN0X2RmJEFkYXB0aXZlCiAgICBwbG90X21hdCA9IGNiaW5kKHBjX2RmWyh0ZXN0X29yaWcrMSk6bnJvdyhwY19kZiksMV0sIG12X2Zjc3QkeWhhdFsxOm50ZXN0XSwgbXZfZmNzdF9hcnQxJHloYXRbMTpudGVzdF0sIG12X2Zjc3RfYXJ0MiR5aGF0WzE6bnRlc3RdLCBtdl9mY3N0X2FydDMkeWhhdFsxOm50ZXN0XSwgdXZfbGlzdCRTQVYsIHV2X2xpc3QkYEFicy4gU2xvcGVgLCB1dl9saXN0JGBJbmQuIEdBUkNIYCwgdXZfbGlzdCRBZGFwdGl2ZSkKICB9CiAgIyBDb3VudCB0aGUgTkFzIGFuZCBwcmludCBhIHdhcm5pbmcKICBwcmludChwYXN0ZSgiTk9URTogVGhlcmUgYXJlICIsIHN1bShpcy5uYShwbG90X21hdCkpLCAiIE5BKHMpIGluIHRoZSBkYXRhc2V0Iiwgc2VwID0gIiIpKQogICMgTGluZWFybHkgaW50ZXJwb2xhdGUgdGhlIE5BcwogIGlmIChuYV9pbnRlcnAgPT0gVFJVRSl7CiAgICAjIEFzc2lnbiB0aGUgcGxvdCBtYXRyaXggdG8gYSBuZXcgdmFsdWUKICAgIHBsb3RfbWF0X25hIDwtIHBsb3RfbWF0CiAgICAjIFByaW50IGEgd2FybmluZwogICAgcHJpbnQoIldBUk5JTkc6IFRoZXJlIHdlcmUgbWlzc2luZyB2YWx1ZXMgaW4gdGhlIHBsb3QgbWF0cml4LiIpCiAgICAjIEludGVycG9sYXRlIHRoZSBOQSdzCiAgICBmb3IgKGkgaW4gMTpuY29sKHBsb3RfbWF0X25hKSl7CiAgICAgICMgSW50ZXJwb2xhdGUgdGhlIGRhdGEKICAgICAgcGxvdF9tYXRbLGldIDwtIG5hLmFwcHJveChwbG90X21hdF9uYVssaV0pCiAgICB9CiAgfQogICMgbW9kZWwgdHlwZSAoMSAtIFNBViwgMiAtIEFTLCAzIC0gR0FSQ0gsIDQgLSBBREFQVElWRSkKICAjIEFkZCBkZXNjcmlwdGl2ZSB0aXRsZXMgb250byB0aGUgcGxvdF9tYXQKICBjb2xuYW1lcyhwbG90X21hdCkgPC0gYyhyZXNwX3ZhciwgIk1WIENBVmlhUiIsICJNViBDQVZpYVIgKyBBUiIsICJNViBDQVZpYVIgKyBTQVYiLCAiTVYgQ0FWaWFSICsgQVMiLCAiU0FWIiwgIkFicy4gU2xvcGUiLCAiSW5kLiBHQVJDSCIsICJBZGFwdGl2ZSIpCiAgIyBjb2xuYW1lcyhwbG90X21hdCkgPC0gYygiU1BZIiwgIk1WIENBVmlhUiIsICJNViBDQVZpYVIgKyBBUiIsICJNViBDQVZpYVIgKyBTQVYiLCAiTVYgQ0FWaWFSICsgQVMiLCAiU0FWIiwgIkFicy4gU2xvcGUiLCAiSW5kLiBHQVJDSCIsICJBZGFwdGl2ZSIpCiAgIyBQbG90IGV2ZXJ5dGhpbmcKICBwbG90ID0gcGx0X2RhdGEocGxvdF9tYXQsIHRhdSA9IHRhdSwgcmVzcF92YXIgPSByZXNwX3ZhciwgbnRlc3QgPSBudGVzdCkKICAjIENhbGN1bGF0ZSBsb3NzZXMKICBsX2xpc3QgPSBnZW5fbG9zc190ZXN0KHBsb3RfbWF0LCB0YXUgPSB0YXUpCiAgIyBQdXQgaW50byB0YWJsZXMKICB0YWJsZXMgPSBwcmV0dHlfdGFibGVzKHBsb3RfbWF0LCBsX2xpc3QsIHRhdSA9IHRhdSwgbnRlc3QgPSBudGVzdCkKICAjIFJ1biB0aGUgZnVuY3Rpb24gZm9yIG9wdGltYWwgcCBhbmQgbQogIHBtX3RhYmxlID0gcHJldHR5X3BtKG9wdF9wcmVkX25sW1szXV0sIG9wdF9wcmVkX2FydDFbWzRdXSwgb3B0X3ByZWRfYXJ0MltbNF1dLCBvcHRfcHJlZF9hcnQzW1s0XV0pCiAgIyBFeHBvcnQgdGhlIG1hdHJpeAogIGlmIChleHBvcnRfY3N2ID09IDEpewogICAgZXhwX2Z1bmModmFyX2ZpbGUgPSBwbG90X21hdCwgcGF0aCwgZmlsZW5hbWUpCiAgfQogICMgUHJpbnQgdGhlIHRhYmxlcyBhbmQgdGhlIHBsb3QKICBwcmludChwbG90KQogIHByaW50KHRhYmxlcykKICBwcmludChwbV90YWJsZSkKICByZXR1cm4obGlzdChwbG90X21hdCwgcGxvdCwgbF9saXN0LCB0YWJsZXMsIHBsb3RfbWF0X25hLCBwbV90YWJsZSkpCn0KYGBgCgoKCmBgYHtyfQojJyBBIGZ1bmN0aW9uIHRvIGlucHV0IHRoZSBWYVIgZmlsZXMsIHBsb3QgdGhlbSBhbmQgZ2VuZXJhdGUgdGFibGVzCiMnCiMnIEBwYXJhbSBmaWxlX3BhdGggLSBmaWxlIHBhdGggdG8gdXNlCiMnIEBwYXJhbSBmaWxlbmFtZSAtIG5hbWUgb2YgdGhlIGZpbGUKIycgQHBhcmFtIHRhdSAtIHF1YW50aWxlIHRvIHVzZQojJyBAcGFyYW0gcmVzcF92YXIgLSByZXNwb25zZSB2YXJpYWJsZSB0byB1c2UgaW4gdGhlIHBsb3QKIycgQHBhcmFtIG50ZXN0IC0gbnVtYmVyIG9mIHRlc3QgcG9pbnRzCiMnIEBwYXJhbSBjbl9pbnB1dCAtIGNvbHVtbiBuYW1lIGlucHV0cwojJwojJyBAcmV0dXJuIC0gYSBsaXN0IG9mIHRoZSB4dHMgZmlsZSwgdGhlIHBsb3QsIHRoZSBsb3NzIGxpc3QsIGFuZCB0YWJsZXMKIycgQGV4cG9ydCAtIGEgcGxvdCBhbmQgdGFibGVzCiMnCiMnIEBleGFtcGxlcyAtIHRlc3QgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfdXNfZXRmLmNzdiIsIDAuMDEpCnZhcl9pbnB1dF9kaXNwID0gZnVuY3Rpb24oZmlsZV9wYXRoLCBmaWxlbmFtZSwgdGF1LCByZXNwX3ZhciA9ICJTUFkiLCBudGVzdCA9IDI1MCwgY25faW5wdXQgPSBjKCJTUFkiLCAiTVYgQ0FWaWFSIiwgIk1WIENBVmlhUiArIEFSIiwgIk1WIENBVmlhUiArIFNBViIsICJNViBDQVZpYVIgKyBBUyIsICJTQVYiLCAiQWJzLiBTbG9wZSIsICJJbmQuIEdBUkNIIiwgIkFkYXB0aXZlIikpewojIHZhcl9pbnB1dF9kaXNwID0gZnVuY3Rpb24oZmlsZV9wYXRoLCBmaWxlbmFtZSwgdGF1LCByZXNwX3ZhciA9ICJTUFkiLCBudGVzdCA9IDI1MCwgY25faW5wdXQgPSBjKCJTUFkiLCAiTVYgQ0FWaWFSIiwgIk1WIENBVmlhUiArIEFSIiwgIk1WIENBVmlhUiArIFNBViIsICJNViBDQVZpYVIgKyBBUyIsICJTQVYiLCAiQWJzLiBTbG9wZSIsICJJbmQuIEdBUkNIIiwgIkFkYXB0aXZlIikpewogICMgSW1wb3J0IGRhdGEKICBwbG90X21hdCA9IHJlYWQuY3N2KHBhc3RlMChmaWxlX3BhdGgsZmlsZW5hbWUpLCBzZXAgPSAiLCIsIGhlYWRlciA9IFQsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKICAjIEZpeCBkYXRlIGZvcm1hdAogIHBsb3RfbWF0JEluZGV4ID0gYXMuRGF0ZShwbG90X21hdCRJbmRleCkKICAjIENvbnZlcnQgdG8gYW4geHRzCiAgcGxvdF9tYXQgPSB4dHMocGxvdF9tYXRbLC0xXSwgb3JkZXIuYnkgPSBwbG90X21hdFssMV0pCiAgIyBGaXggY29sdW1uIG5hbWVzCiAgY29sbmFtZXMocGxvdF9tYXQpIDwtIGNuX2lucHV0CiAgIyBQbG90IGV2ZXJ5dGhpbmcKICBwbHRfZGF0YShwbG90X21hdCwgdGF1ID0gdGF1LCByZXNwX3ZhciA9IHJlc3BfdmFyLCBudGVzdCA9IG50ZXN0KQogICMgcGxvdCA9IHBsdF9kYXRhKHBsb3RfbWF0LCB0YXUgPSB0YXUsIHJlc3BfdmFyID0gcmVzcF92YXIsIG50ZXN0ID0gbnRlc3QpCiAgIyBDYWxjdWxhdGUgbG9zc2VzCiAgbF9saXN0ID0gZ2VuX2xvc3NfdGVzdChwbG90X21hdCwgdGF1ID0gdGF1KQogICMgUHV0IGludG8gdGFibGVzCiAgZGYgPSBhcy5kYXRhLmZyYW1lKHJiaW5kKGxfbGlzdFtbMV1dLCBsX2xpc3RbWzJdXSkpCiAgIyBDYWxjdWxhdGUgaW5pdGFsIGFuZCBlbmRpbmcgdGltZSB2YWx1ZQogIHN0YXJ0ID0gaW5kZXgocGxvdF9tYXQpWzFdCiAgZW5kID0gaW5kZXgocGxvdF9tYXQpW25yb3cocGxvdF9tYXQpXQogICMgQWRkIHJvdy9jb2x1bW4gbmFtZXMKICBjb2xuYW1lcyhkZikgPC0gY29sbmFtZXMocGxvdF9tYXRbLC0xXSkKICByb3duYW1lcyhkZikgPC0gYygiTG9zc2VzIiwgIlZhUiBCcmVha3MgKCUpIikKICAjIENvbnZlcnQgdG8gYSB0YWJsZQogIHByaW50KGRmLCBkaWdpdHMgPSAzKQogICMgcHJpbnQoZm9ybWF0dGFibGUoZGYsIGRpZ2l0cyA9IDMpKQogICMgZGYgJT4lIGthYmxlKGNhcHRpb24gPSBwYXN0ZSgiQ29tcGFyaXNvbiBvZiBWYVIgTWV0aG9kcyBmb3IgYSAiLCB0YXUqMTAwLCAiJSBWYVIiLCBzZXAgPSAiIiksIGRpZ2l0cyA9IDMpICU+JSBrYWJsZV9zdHlsaW5nKCJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpICU+JSBrYWJsZV9zdHlsaW5nKCkgJT4lIGZvb3Rub3RlKGdlbmVyYWwgPSBwYXN0ZSgiQ2FsY3VsYXRlZCB1c2luZyIsIG50ZXN0LCAidHJhZGluZyBkYXlzIGZyb20iLCBhcy5EYXRlKHN0YXJ0KSwgInRvIiwgYXMuRGF0ZShlbmQpKSkKICAjIHBtX3RhYmxlID0gcHJldHR5X3RhYmxlcyhwbG90X21hdCwgbF9saXN0LCB0YXUgPSB0YXUsIG50ZXN0ID0gbnRlc3QpCiAgIyBQcmludCB0aGUgdGFibGVzIGFuZCB0aGUgcGxvdAogICMgcHJpbnQocGxvdCkKICAjIHByaW50KHRhYmxlcykKICAjIHByaW50KHBtX3RhYmxlKQogICMgUmV0dXJuIHRoZSB4dHMsIHRoZSBwbG90LCB0aGUgbG9zcyBsaXN0LCBhbmQgdGhlIHRhYmxlcwogIHJldHVybihsaXN0KHBsb3RfbWF0KSkKICAjIHJldHVybihsaXN0KHBsb3RfbWF0LCBwbG90LCBsX2xpc3QsIHRhYmxlcykpCn0KYGBgCgoKIyMgMjAwOCBFbmRpbmcKCiMjIyBVLlMuIEVURnMKCmBgYHtyfQojIHJldHVybihsaXN0KHBsb3RfbWF0LCBwbG90LCBsX2xpc3QsIHRhYmxlcykpCgojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMDhfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfdXNfZXRmLmNzdiIsIDAuMDEpCiMgcHJldHR5X3RhYmxlcyh2MV8yMDA4X3VzZXRmW1sxXV0sIHYxXzIwMDhfdXNldGZbWzNdXSwgdGF1ID0gMC4wMSwgbnRlc3QgPSAyNTApCnY1XzIwMDhfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMDhfdXNfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDA4X3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAwOF91c19ldGYuY3N2IiwgMC4xMCkKCiMgaGVhZCh2MTBfMjAwOF91c2V0ZltbMV1dKQojIHYxMF8yMDA4X3VzZXRmCmBgYAoKVGhlIHJlc3VsdHMgZm9yIHRoZSBVLlMuIEVURnMgY2xlYXJseSBzaG93IHRoYXQgdGhlIHVuaXZhcmlhdGUgbW9kZWwgb3V0cGVyZm9ybXMgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbCBkdXJpbmcgdGhlIGdyZWF0IHJlY2Vzc2lvbi4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMDggLSAxc3Qgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMDhfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMDhfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDA4X3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMDhfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAwOF91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAwOF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMDhfdXNldGZbWzFdXSkKYGBgCgojIyMgR2xvYmFsIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMDhfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzFwY18yMDA4X2dsb2JfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMDhfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzVwY18yMDA4X2dsb2JfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDA4X2dsb2JldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMDhfZ2xvYl9ldGYuY3N2IiwgMC4xMCkKYGBgCgpXaGlsZSB0aGUgbW9kZWwgd2l0aCB0aGUgZ2xvYmFsIEVURnMgYXMgcHJlZGljdG9ycyBwZXJmb3JtcyBiZXR0ZXIgdGhhbiB0aGUgbW9kZWwgd2l0aCBVLlMuIEVURnMsIHRoZSB1bml2YXJpYXRlIENBVmlhUiBtb2RlbCBvdXRwZXJmb3JtcyB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAwOCAtIDJuZCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAwOF9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAwOF9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDA4X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAwOF9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDA4X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAwOF9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAwOF9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAwOF91c2V0ZltbMV1dKQpgYGAKCiMjIyBDb21tb2RpdHkgRVRGcwoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAwOCAtIDNyZCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAwOF9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDA4X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDA4X2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAwOF9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDA4X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMDhfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAwOF9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAwOF91c2V0ZltbMV1dKQpgYGAKCgoKIyMjIEJvbmQgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAwOF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfYm9uZF9ldGYuY3N2IiwgMC4wMSkKdjVfMjAwOF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMDhfYm9uZF9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMDhfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAwOF9ib25kX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkFzIHdpdGggdGhlIHByZXZpb3VzIHR3byBydW5zLCB0aGUgdW5pdmFyaWF0ZSBtb2RlbCBvdXRwZXJmb3JtcyB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsLgoKYGBge3J9CiMgaVNoYXJlcyAxLTMgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFNIWSkKIyBpU2hhcmVzIDctMTAgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKElFRikKIyBpU2hhcmVzIDIwKyBZZWFyIFRyZWFzdXJ5IEJvbmQgRnVuZCAoVExUKQojIGlTaGFyZXMgaUJveHggJCBJbnZlc3RtZW50IEdyYWRlIENvcnBvcmF0ZSBCb25kIEVURiAoTFFEKQoKIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDA4IC0gNHRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDA4X2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMDhfYm9uZF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAwOF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMDhfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDA4X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAwOF9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDA4X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDA4X3VzZXRmW1sxXV0pCmBgYAoKIyMjIEFsbCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDA4X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMDhfYWxsX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDA4X2FsbGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMDhfYWxsX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAwOF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAwOF9hbGxfZXRmLmNzdiIsIDAuMTApCmBgYAoKV2hpbGUgdGhlIGluY2x1c2lvbiBvZiBtb3JlIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBzZWVtcyB0byBoZWxwIHRoZSBmb3JlY2FzdCwgdGhlIHVuaXZhcmlhdGUgbW9kZWwgb3V0cGVyZm9ybXMgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbC4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMDggLSA1dGggc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMDhfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMDgtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAwOF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDA4X2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDQtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDA4LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAwOF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMDhfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAwOF9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA0LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAwOC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDA4X2FsbF9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMDhfdXNldGZbWzFdXSkKYGBgCgojIyAyMDEwIEVuZGluZwoKIyMjIFUuUy4gRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxMF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl8xcGNfMjAxMF91c19ldGYuY3N2IiwgMC4wMSkKdjVfMjAxMF91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl81cGNfMjAxMF91c19ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTBfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDEwX3VzX2V0Zi5jc3YiLCAwLjEwKQpgYGAKClRoZSByZXN1bHRzIGFyZSBtdWNoIGJldHRlciBmb3IgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbCBoZXJlIGR1cmluZyBhIG1vcmUgYmVuaWduIHBlcmlvZC4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTAgLSAxc3Qgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTBfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTBfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDEwX3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTBfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxMF91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxMF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTBfdXNldGZbWzFdXSkKYGBgCgojIyMgR2xvYmFsIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMTBfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzFwY18yMDEwX2dsb2JfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMTBfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzVwY18yMDEwX2dsb2JfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDEwX2dsb2JldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTBfZ2xvYl9ldGYuY3N2IiwgMC4xMCkKYGBgCgpBcyB3aXRoIHRoZSBVLlMuIEVURnMsIHRoZSByZXN1bHRzIGFyZSBiZXR0ZXIuCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDEwIC0gMm5kIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDEwX2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDEwX2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDEwX2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTBfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDEwX2dsb2JfZXRmID0gY2F2X3NpbXVsKGMoIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMTAsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDEwX2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDEwX3VzZXRmW1sxXV0pCmBgYAoKIyMjIENvbW1vZGl0eSBFVEZzCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDEwIC0gM3JkIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDEwX2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTBfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxMF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTBfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDEwX2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxMF9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDEwX2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDEwX3VzZXRmW1sxXV0pCmBgYAoKIyMjIEJvbmQgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxMF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTBfYm9uZF9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxMF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTBfYm9uZF9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTBfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxMF9ib25kX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkFzIHdpdGggdGhlIHByZXZpb3VzIHR3byBydW5zLCB0aGUgcmVzdWx0cyBmcm9tIHRoZSBib25kIEVURnMgYXJlIGJldHRlciB0aGFuIHRob3NlIGZyb20gMjAwOC4KCmBgYHtyfQojIGlTaGFyZXMgMS0zIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChTSFkpCiMgaVNoYXJlcyA3LTEwIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChJRUYpCiMgaVNoYXJlcyAyMCsgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFRMVCkKIyBpU2hhcmVzIGlCb3h4ICQgSW52ZXN0bWVudCBHcmFkZSBDb3Jwb3JhdGUgQm9uZCBFVEYgKExRRCkKCiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxMCAtIDR0aCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxMF9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDEwX2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTBfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDEwX2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxMF9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDEwX3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTBfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxMF9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxMF91c2V0ZltbMV1dKQpgYGAKCiMjIyBBbGwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxMF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzFwY18yMDEwX2FsbF9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxMF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzVwY18yMDEwX2FsbF9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTBfYWxsZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTBfYWxsX2V0Zi5jc3YiLCAwLjEwKQpgYGAKClRoZSBpbmNsdXNpb24gb2YgYWxsIHByZWRpY3RvcnMgcmV2ZWFscyBzaW1pbGFyIHJlc3VsdHMgZm9yIHRoZSBtdWx0aXZhcmlhdGUgbW9kZWxzIGFzIHRoZSBwcmV2aW91cyBmb3JlY2FzdHM7IHRoZSByZXN1bHRzIGFyZSBnZW5lcmFsbHkgaW4tbGluZSB0aGUgdW5pdmFyaWF0ZSBDQVZpYVIgbW9kZWwuCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDEwIC0gNXRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDEwX2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMDYtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDEwLTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTBfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDEwX3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxMF9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDA2LTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxMC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTBfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDEwX3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTBfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAwNi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTAtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxMF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDEwX3VzZXRmW1sxXV0pCmBgYAoKIyMgMjAxNCBFbmRpbmcKCiMjIyBVLlMuIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMTRfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTRfdXNfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMTRfdXNldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTRfdXNfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDE0X3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNF91c19ldGYuY3N2IiwgMC4xMCkKYGBgCgpBcyB3aXRoIHRoZSByZXN1bHRzIGluIDIwMTQsIHRoZSByZXN1bHRzIGZyb20gdGhlIFUuUy4gRVRGcyBzaG93cyBhIHNpbWlsYXIgcXVhbGl0eSBvZiBwcmVkaWN0aW9ucy4KCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTQgLSAxc3Qgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTRfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTRfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE0X3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTRfdXNfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNF91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4xMCwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNF91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTRfdXNldGZbWzFdXSkKYGBgCgojIyMgR2xvYmFsIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMTRfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzFwY18yMDE0X2dsb2JfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMTRfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzVwY18yMDE0X2dsb2JfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDE0X2dsb2JldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTRfZ2xvYl9ldGYuY3N2IiwgMC4xMCkKYGBgCgpUaGUgcmVzdWx0cyBzaG93IHRoYXQgdGhlIG11bHRpdmFyaWF0ZSBwcmVkaWN0aW9ucyBhcmUgb2Ygc2ltaWxhciBxdWFsaXR5IHRvIHRoZSBwcmVkaWN0aW9ucyBmcm9tIHRoZSB1bml2YXJpYXRlIG1vZGVsLiAKCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTQgLSAybmQgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTRfZ2xvYl9ldGYgPSBjYXZfc2ltdWwoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAxMCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCwgdGF1ID0gMC4wMSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTRfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxNF91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTRfZ2xvYl9ldGYgPSBjYXZfc2ltdWwoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAxMCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNF9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTRfZ2xvYl9ldGYgPSBjYXZfc2ltdWwoYygiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAxMCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMTRfZ2xvYl9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTRfdXNldGZbWzFdXSkKYGBgCgojIyMgQ29tbW9kaXR5IEVURnMKCmBgYHtyfQojIDElLCA1JSwgMTAlIFZhUiAtIDIwMTQgLSAzcmQgc2V0IG9mIHByZWRpY3RvcnMKIyB2YXJfMXBjXzIwMTRfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNF9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxNF9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsdGF1ID0gMC4wNSwgcHJpbnRfbWRsID0gMSwgcHJpbnRfbXAgPSAxLCBwYXRoID0gIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfY29tbV9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTRfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxNF91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDE0X2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xMHBjXzIwMTRfY29tbV9ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xMHBjXzIwMTRfdXNldGZbWzFdXSkKYGBgCgojIyMgQm9uZCBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDE0X2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl8xcGNfMjAxNF9ib25kX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDE0X2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl81cGNfMjAxNF9ib25kX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxNF9ib25kZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYm9uZF9FVEZfcnVucy8iLCJ2YXJfMTBwY18yMDE0X2JvbmRfZXRmLmNzdiIsIDAuMTApCmBgYAoKQXMgd2l0aCB0aGUgb3RoZXIgdHdvIHNldHMgb2YgcmVncmVzc29ycywgdGhlIHJlc3VsdHMgaGVyZSBzaG93IHRoYXQgdGhlIG11bHRpdmFyaWF0ZSBwcmVkaWN0aW9ucyBhcmUgb2Ygc2ltaWxhciBxdWFsaXR5IHRvIHRoZSBwcmVkaWN0aW9ucyBmcm9tIHRoZSB1bml2YXJpYXRlIG1vZGVsLiAKCmBgYHtyfQojIGlTaGFyZXMgMS0zIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChTSFkpCiMgaVNoYXJlcyA3LTEwIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChJRUYpCiMgaVNoYXJlcyAyMCsgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFRMVCkKIyBpU2hhcmVzIGlCb3h4ICQgSW52ZXN0bWVudCBHcmFkZSBDb3Jwb3JhdGUgQm9uZCBFVEYgKExRRCkKCiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNCAtIDR0aCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNF9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDE0X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTRfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE0X2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNF9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTRfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNF9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNF91c2V0ZltbMV1dKQpgYGAKCiMjIyBBbGwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxNF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzFwY18yMDE0X2FsbF9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxNF9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzVwY18yMDE0X2FsbF9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTRfYWxsZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTRfYWxsX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkluY2x1ZGluZyBhbGwgdGhlIEVURnMgYXMgcmVncmVzc29ycyBwcm92aWRlcyBhIG11bHRpdmFyaWF0ZSBmb3JlY2FzdCB3aXRoIHNpbWlsYXIgYWNjdXJhY3kgdG8gdGhhdCBvZiB0aGUgdW5pdmFyaWF0ZSBtb2RlbC4gCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE0IC0gNXRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE0X2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTAtMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE0LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTRfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxNF9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEwLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNC0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTRfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE0X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTRfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMC0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTQtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNF9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE0X3VzZXRmW1sxXV0pCmBgYAoKCiMjIDIwMTYgRW5kaW5nCgojIyMgVS5TLiBFVEZzCgpgYGB7cn0KIyBDYWxsIHRoZSBhYm92ZSBmdW5jdGlvbgp2MV8yMDE2X3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzFwY18yMDE2X3VzX2V0Zi5jc3YiLCAwLjAxKQp2NV8yMDE2X3VzZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfVVNfRVRGX3J1bnMvIiwidmFyXzVwY18yMDE2X3VzX2V0Zi5jc3YiLCAwLjA1KQp2MTBfMjAxNl91c2V0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTZfdXNfZXRmLmNzdiIsIDAuMTApCmBgYAoKQXMgd2l0aCB0aGUgZm9yZWNhc3QgaW4gMjAxMCBhbmQgMjAxNCwgaW5jbHVkaW5nIHRoZSBVLlMuIEVURnMgYXMgcHJlZGljdG9ycyBpbiB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsIGdpdmVzIHNpbWlsYXIgcmVzdWx0cyB0byB0aGF0IG9mIHRoZSB1bml2YXJpYXRlIG1vZGVsLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNiAtIDFzdCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNl91c19ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDksIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNl91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl8xcGNfMjAxNl91c2V0ZltbMV1dKQoKIyB2YXJfNXBjXzIwMTZfdXNfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA5LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX1VTX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNl91c19ldGYuY3N2IiwgdXZfbGlzdCA9IHZhcl81cGNfMjAxNl91c2V0ZltbMV1dKQoKIyB2YXJfMTBwY18yMDE2X3VzX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gOSwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9VU19FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMTBwY18yMDE2X3VzX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNl91c2V0ZltbMV1dKQpgYGAKCiMjIyBHbG9iYWwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxNl9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfMXBjXzIwMTZfZ2xvYl9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxNl9nbG9iZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfZ2xvYl9FVEZfcnVucy8iLCJ2YXJfNXBjXzIwMTZfZ2xvYl9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTZfZ2xvYmV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwidmFyXzEwcGNfMjAxNl9nbG9iX2V0Zi5jc3YiLCAwLjEwKQpgYGAKClRoZSBnbG9iYWwgRVRGcyBhcyBwcmVkaWN0b3JzIHByb3ZpZGUgc29saWQgcmVzdWx0cyBhcyB3ZWxsLgoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNiAtIDJuZCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNl9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLCB0YXUgPSAwLjAxLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9nbG9iX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl8xcGNfMjAxNl9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxNl9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzVwY18yMDE2X2dsb2JfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfNXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzEwcGNfMjAxNl9nbG9iX2V0ZiA9IGNhdl9zaW11bChjKCJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDEwLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2dsb2JfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNl9nbG9iX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNl91c2V0ZltbMV1dKQpgYGAKCiMjIyBDb21tb2RpdHkgRVRGcwoKYGBge3J9CiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNiAtIDNyZCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNl9jb21tX2V0ZiA9IGNhdl9zaW11bChjKCJEQkEiLCAiREJDIiwgIkRCRSIsICJEQkIiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDE2X2NvbW1fZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE2X2NvbW1fZXRmID0gY2F2X3NpbXVsKGMoIkRCQSIsICJEQkMiLCAiREJFIiwgIkRCQiIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9jb21tX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNl9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTZfY29tbV9ldGYgPSBjYXZfc2ltdWwoYygiREJBIiwgIkRCQyIsICJEQkUiLCAiREJCIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2NvbW1fRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNl9jb21tX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNl91c2V0ZltbMV1dKQpgYGAKCiMjIyBCb25kIEVURnMKCmBgYHtyfQojIENhbGwgdGhlIGFib3ZlIGZ1bmN0aW9uCnYxXzIwMTZfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzFwY18yMDE2X2JvbmRfZXRmLmNzdiIsIDAuMDEpCnY1XzIwMTZfYm9uZGV0ZiA9IHZhcl9pbnB1dF9kaXNwKCIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwidmFyXzVwY18yMDE2X2JvbmRfZXRmLmNzdiIsIDAuMDUpCnYxMF8yMDE2X2JvbmRldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTZfYm9uZF9ldGYuY3N2IiwgMC4xMCkKYGBgCgpBcyB3aXRoIHRoZSBVLlMuIGFuZCBHbG9iYWwgRVRGcywgdGhlIGJvbmQgRVRGcyBwcm92aWRlIGdvb2QgcmVzdWx0cy4KCmBgYHtyfQojIGlTaGFyZXMgMS0zIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChTSFkpCiMgaVNoYXJlcyA3LTEwIFllYXIgVHJlYXN1cnkgQm9uZCBGdW5kIChJRUYpCiMgaVNoYXJlcyAyMCsgWWVhciBUcmVhc3VyeSBCb25kIEZ1bmQgKFRMVCkKIyBpU2hhcmVzIGlCb3h4ICQgSW52ZXN0bWVudCBHcmFkZSBDb3Jwb3JhdGUgQm9uZCBFVEYgKExRRCkKCiMgMSUsIDUlLCAxMCUgVmFSIC0gMjAxNiAtIDR0aCBzZXQgb2YgcHJlZGljdG9ycwojIHZhcl8xcGNfMjAxNl9ib25kX2V0ZiA9IGNhdl9zaW11bChjKCJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDQsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzFwY18yMDE2X2JvbmRfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMXBjXzIwMTZfdXNldGZbWzFdXSkKCiMgdmFyXzVwY18yMDE2X2JvbmRfZXRmID0gY2F2X3NpbXVsKGMoIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gNCwgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjA1LCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9ib25kX0VURl9ydW5zLyIsIGZpbGVuYW1lID0gInZhcl81cGNfMjAxNl9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTZfYm9uZF9ldGYgPSBjYXZfc2ltdWwoYygiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSA0LCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMTAsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2JvbmRfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNl9ib25kX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzEwcGNfMjAxNl91c2V0ZltbMV1dKQpgYGAKCiMjIyBBbGwgRVRGcwoKYGBge3J9CiMgQ2FsbCB0aGUgYWJvdmUgZnVuY3Rpb24KdjFfMjAxNl9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzFwY18yMDE2X2FsbF9ldGYuY3N2IiwgMC4wMSkKdjVfMjAxNl9hbGxldGYgPSB2YXJfaW5wdXRfZGlzcCgiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwidmFyXzVwY18yMDE2X2FsbF9ldGYuY3N2IiwgMC4wNSkKdjEwXzIwMTZfYWxsZXRmID0gdmFyX2lucHV0X2Rpc3AoIi9Vc2Vycy9zdGV2ZW5tb2VuL0RvY3VtZW50cy9HaXRIdWIvQ0FWaWFSX01TX3RoZXNpcy9EYXRhX0V4cG9ydC9TUFlfYWxsX0VURl9ydW5zLyIsInZhcl8xMHBjXzIwMTZfYWxsX2V0Zi5jc3YiLCAwLjEwKQpgYGAKCkluY2x1ZGluZyBhbGwgRVRGcyBhcyBwcmVkaWN0b3JzIHlpZWxkcyBnb29kIHF1YWxpdHkgcmVzdWx0cyBmb3IgdGhlIDIwMTYgdGVzdCBwZXJpb2QuCgpgYGB7cn0KIyAxJSwgNSUsIDEwJSBWYVIgLSAyMDE2IC0gNXRoIHNldCBvZiBwcmVkaWN0b3JzCiMgdmFyXzFwY18yMDE2X2FsbF9ldGYgPSBjYXZfc2ltdWwoYygiWExVIiwgIlhMUCIsICJYTFYiLCAiWExLIiwgIlhMWSIsICJYTEkiLCAiWExGIiwgIlhMQiIsICJYTEUiLCAiSlhJIiwgIktYSSIsICJJWEoiLCAiSVhQIiwgIklYTiIsICJSWEkiLCAiRVhJIiwgIklYRyIsICJNWEkiLCAiSVhDIiwgIlNIWSIsICJJRUYiLCAiVExUIiwgIkxRRCIpLCByZXNwX3ZhciA9ICJTUFkiLCBzdGFydF9kYXRlID0gIjIwMTItMDEtMDEiLCBlbmRfZGF0ZSA9ICIyMDE2LTEyLTMxIiwgbnZhbCA9IDI1MCwgbnRlc3QgPSAyNTAsIGxvd19tID0gMSwgaGlnaF9tID0gMjMsIGxvd19wID0gMSwgaGlnaF9wID0gMTAsIHRhdSA9IDAuMDEsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfMXBjXzIwMTZfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzFwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl81cGNfMjAxNl9hbGxfZXRmID0gY2F2X3NpbXVsKGMoIlhMVSIsICJYTFAiLCAiWExWIiwgIlhMSyIsICJYTFkiLCAiWExJIiwgIlhMRiIsICJYTEIiLCAiWExFIiwgIkpYSSIsICJLWEkiLCAiSVhKIiwgIklYUCIsICJJWE4iLCAiUlhJIiwgIkVYSSIsICJJWEciLCAiTVhJIiwgIklYQyIsICJTSFkiLCAiSUVGIiwgIlRMVCIsICJMUUQiKSwgcmVzcF92YXIgPSAiU1BZIiwgc3RhcnRfZGF0ZSA9ICIyMDEyLTAxLTAxIiwgZW5kX2RhdGUgPSAiMjAxNi0xMi0zMSIsIG52YWwgPSAyNTAsIG50ZXN0ID0gMjUwLCBsb3dfbSA9IDEsIGhpZ2hfbSA9IDIzLCBsb3dfcCA9IDEsIGhpZ2hfcCA9IDEwLHRhdSA9IDAuMDUsIHByaW50X21kbCA9IDEsIHByaW50X21wID0gMSwgcGF0aCA9ICIvVXNlcnMvc3RldmVubW9lbi9Eb2N1bWVudHMvR2l0SHViL0NBVmlhUl9NU190aGVzaXMvRGF0YV9FeHBvcnQvU1BZX2FsbF9FVEZfcnVucy8iLCBmaWxlbmFtZSA9ICJ2YXJfNXBjXzIwMTZfYWxsX2V0Zi5jc3YiLCB1dl9saXN0ID0gdmFyXzVwY18yMDE2X3VzZXRmW1sxXV0pCgojIHZhcl8xMHBjXzIwMTZfYWxsX2V0ZiA9IGNhdl9zaW11bChjKCJYTFUiLCAiWExQIiwgIlhMViIsICJYTEsiLCAiWExZIiwgIlhMSSIsICJYTEYiLCAiWExCIiwgIlhMRSIsICJKWEkiLCAiS1hJIiwgIklYSiIsICJJWFAiLCAiSVhOIiwgIlJYSSIsICJFWEkiLCAiSVhHIiwgIk1YSSIsICJJWEMiLCAiU0hZIiwgIklFRiIsICJUTFQiLCAiTFFEIiksIHJlc3BfdmFyID0gIlNQWSIsIHN0YXJ0X2RhdGUgPSAiMjAxMi0wMS0wMSIsIGVuZF9kYXRlID0gIjIwMTYtMTItMzEiLCBudmFsID0gMjUwLCBudGVzdCA9IDI1MCwgbG93X20gPSAxLCBoaWdoX20gPSAyMywgbG93X3AgPSAxLCBoaWdoX3AgPSAxMCx0YXUgPSAwLjEwLCBwcmludF9tZGwgPSAxLCBwcmludF9tcCA9IDEsIHBhdGggPSAiL1VzZXJzL3N0ZXZlbm1vZW4vRG9jdW1lbnRzL0dpdEh1Yi9DQVZpYVJfTVNfdGhlc2lzL0RhdGFfRXhwb3J0L1NQWV9hbGxfRVRGX3J1bnMvIiwgZmlsZW5hbWUgPSAidmFyXzEwcGNfMjAxNl9hbGxfZXRmLmNzdiIsIHV2X2xpc3QgPSB2YXJfMTBwY18yMDE2X3VzZXRmW1sxXV0pCmBgYAoKIyBDb25jbHVzaW9ucyBhbmQgRnV0dXJlIFdvcmsKClRoZSBwcm9ibGVtIG9mIGhvdyB0byBwcmVkaWN0IGEgbG93IHF1YW50aWxlIG9mIGEgc3RvY2sncyBsb2cgcmV0dXJuIHdoZW4gdGhlIHRyYWluaW5nIHNhbXBsZSBpcyBzdWJzdGFudGlhbGx5IGRpZmZlcmVudCB0aGFuIHRoZSB0ZXN0IHNjZW5hcmlvIGlzIGFuIGVub3Jtb3VzbHkgZGlmZmljdWx0IHByb2JsZW0uIEFsbW9zdCBheGlvbWF0aWNhbGx5LCB0aGUgZGlzdHJpYnV0aW9uIGlzIG5vbnN0YXRpb25hcnkgb3ZlciB0aW1lLiBIb3cgaXMgaXQgcG9zc2libGUgdG8gcHJlZGljdCB0aGUgcmV0dXJuIG9mIGFuIGluZGV4IGxpa2UgdGhlIFMmUDUwMCBkdXJpbmcgYSBwZXJpb2Qgb2YgbWFya2V0IHR1cm1vaWwgc3VjaCBhcyB0aGUgZ3JlYXQgcmVjZXNzaW9uPyBXaGlsZSB0aGUgQ0FWaWFSIG1vZGVsIHBlcmZvcm1zIGNvbXBhcmF0aXZlbHkgd2VsbCBkdXJpbmcgdGltZXMgb2Ygc3RyZXNzLCBpdCBwZXJmb3JtcyBhYm91dCB0aGUgc2FtZSBhcyB0aGUgbXVsdGl2YXJpYXRlIG1vZGVsIGR1cmluZyBtb3JlIGJlbmlnbiBlY29ub21pYyBwZXJpb2RzLgoKVGhpcyBjb25jbHVzaW9uIGRyYXduIGZyb20gdGhlIGFib3ZlIHJlc3VsdHMgbWlnaHQgc3VwcG9ydCB0aGUgbm90aW9uIG9mIGNvbWJpbmluZyB0aGUgdHdvIG1vZGVscyBpbiBzb21lIHNvcnQgb2YgYSBtaXh0dXJlIG1vZGVsIC0gYWltaW5nIHRvIHVzZSB0aGUgYmFza2V0IG9mIEVURnMgZHVyaW5nIGdvb2QgdGltZXMsIGFuZCB1c2UgdGhlIENBVmlhUiBBUk1BIHNwZWNpZmljYXRpb24gZHVyaW5nIGJhZCB0aW1lcy4gVGhlIGFwcHJvYWNoIG9mIHVzaW5nIEVURnMgYWxsb3dzIGEgcHJlZGljdGlvbiBiYXNlZCBvbiBmb3J3YXJkLWxvb2tpbmcgZXhwZWN0YXRpb25zIG9mIGZ1bmRhbWVudGFsIGZhY3RvcnMuIEluZGVlZCwgRVRGcyBhcmUganVzdCBiYXNrZXRzIG9mIGluZGl2aWR1YWwgc3RvY2tzIG9yIGJvbmRzLCBhbmQgdGhvc2Ugc2VjdXJpdGllcyBhcmUgKGluIHRoZW9yeSkgYmFzZWQgb24gcmF0aW9uYWwgZXhwZWN0YXRpb25zIGFib3V0IGZ1dHVyZSByZXNvdXJjZXMsIG1hcmtldCBjb25kaXRpb25zLCBldGMgLSB0aGUgbWljcm9mb3VuZGF0aW9ucyBvZiB3aGF0IGRyaXZlcyBvdXIgZWNvbm9teS4gVGhlIEFSTUEgc3BlY2lmaWNhdGlvbiwgd2hpbGUgcHJhY3RpY2FsbHkgYW5kIHN0YXRpc3RpY2FsbHkgc291bmQsIGlzIGNvbnRyYWRpY3RlZCBieSBlY29ub21pYyB0aGVvcnkgYW5kIHByYWN0aWNlIC0gdGhlIHdlYWsgZm9ybSBvZiB0aGUgZWZmaWNpZW50IG1hcmtldCBoeXBvdGhlc2lzIHN0YXRlcyB0aGF0IGl0IGlzIGltcG9zc2libGUgdG8gZm9yZWNhc3QgZnV0dXJlIHZhbHVlcyBvZiBhc3NldCBwcmljZXMgdXNpbmcgcGFzdCB2YWx1ZXMuIEJ1dCBwZXJoYXBzIHRoaXMgdmlldyBpcyBpbmNvbXBsZXRlLgoKQW55IG1vZGVsIHRoYXQgYXR0ZW1wdHMgdG8gY2FwdHVyZSByZWxhdGlvbnNoaXBzIGluIHRoZSByZWFsIHdvcmxkIHdpbGwgb25seSB3b3JrIHVudGlsIGFuIG9taXR0ZWQgdmFyaWFibGUgaXMgZm91bmQuIFRoZSBlbGVnYW5jZSBvZiB0aGUgbXVsdGl2YXJpYXRlIENBVmlhUiBtb2RlbCBpcyB0aGF0IGl0IHByb3ZpZGVzIGluc2lnaHQgaW50byB3aHkgYSBwcmVkaWN0aW9uIGlzIHdyb25nOyB0aGUgY2hhbmdlIGluIHRoZSBhbmdsZSBiZXR3ZWVuIHJlc3VsdGFudCB2ZWN0b3JzIGlzIGEgc2Vuc2libGUgbWVhc3VyZW1lbnQgb2YgZWNvbm9taWMgY2hhbmdlcG9pbnRzIChDSEFOR0UpLiBIb3dldmVyLCBlcnJvcnMgaW4gdGhlIHdvcmxkIGFyZSBjb3N0bHksIGFuZCBpdCdzIHdpc2hmdWwgdGhpbmtpbmcgdG8gc2F5IHRoYXQgZXhwbGFpbmluZyB3aHkgdGhlIGVycm9yIG9jY3VyZWQgaXMgc3VmZmljaWVudC4KCkFzIHN1Y2gsIGZvciBmdXR1cmUgd29yayBpdCdzIHdvcnRoIGV4cGxvcmluZyB0aGUgbm90aW9uIG9mIHdlaWdodGluZyBhbiBBUk1BLWFwcHJvYWNoIG1vcmUgaGVhdmlseSB3aGVuIHByZWRpY3Rpb25zIHVzaW5nIGZ1bmRhbWVudGFscyB3ZXJlIHRvbyBoaWdoLCB0aGVuIG5vdCBvbmx5IHdvdWxkIHRoaXMgYWZ0ZXItdGhlLWZhY3QgcmVjb2duaXRpb24gYmUgYWNoaWV2ZXMsIGJ1dCBhbHNvIGEgaGllcmFyY2hpY2FsIG1vZGVsIHRoYXQgY2FwdHVyZXMgZnVuZGFtZW50YWwgcmVsYXRpb25zaGlwcyBpbiB0aGUgZWNvbm9teSBhbmQgcG90ZW50aWFsbHkgY2hhbmdlcyBvdXIgdW5kZXJzdGFuZGluZyBvZiBhc3NldCBwcmljZXMgaW4gZ2VuZXJhbCAtIGEgc3ludGhlc2lzIGJldHdlZW4gS2V5bmVzJyBhbmltYWwgc3Bpcml0cyBkdXJpbmcgYSB0aW1lIG9mIHNldmVyZSBjcmlzaXM7IHdoZXJlIGEgbW9kZWwgY2Fubm90IGV4cGxhaW4gc2hpZnRzLCBhbmQgYSBtb3JlIHJhdGlvbmFsIHdvcmxkIHRoYXQgZXhwbGFpbnMgb3RoZXIgcGVyaW9kcy4gSW4gYWRkaXRpb24gdG8gc2lnbmlmaWNhbnQgcHJlZGljdGl2ZSBwb3dlciBiZWNhdXNlIG9mIHRoZSBzd2l0Y2hpbmcgYmV0d2VlbiB0aGUgdHdvIHdvcmxkcywgdGhlcmUncyBhbHNvIGFuIGVsZWdhbnQgZXhwbGFuYXRpb247IGEgd2F5IHRvIGV4cGxhaW4gY2hhbmdlcyBpbiB0aGUgdXNlZnVsbmVzcyBvZiB0aGUgdW5kZXJwaW5uaW5ncyBpbiB0aGUgZWNvbm9teS4gQmVjYXVzZSBvZiB0aGUgZmxleGliaWxpdHkgb2YgdGhlIG1vZGVsLCBpdCdzIGVudGlyZWx5IHBvc3NpYmxlIHRoYXQgYSB3aG9sZSBnYW11dCBvZiB2YXJpYWJsZXMgY291bGQgYmUgdG9zc2VkIGluIGFuZCBiYWNrdGVzdGVkIHRvIHdoZW4gImNoYW5nZXBvaW50cyIgb2NjdXJyZWQuIAoKQWRkaXRpb25hbCBmdXR1cmUgd29yayBpbnZvbHZlcyBkZXZlbG9waW5nIHRoZW9yZXRpY2FsIGd1YXJhbnRlZXMgb24gdGhlIHBhcmFtZXRlcnMgaW4gdGhlIG11bHRpdmFyaWF0ZSBDQVZpYVIgbW9kZWwuIE9uZSBhZHZhbnRhZ2Ugb2YgYm90aCB0aGUgZGlmZnVzaW9uIGluZGV4IG1vZGVsIGFuZCB0aGUgQ0FWaWFSIG1vZGVsIGlzIHRoYXQgYm90aCBoYXZlIHRoZW9yZW1zIGFib3V0IGFzeW1wdG90aWMgbm9ybWFsaXR5IGFuZCBjb25zaXN0ZW5jeSBbQ09ORklSTV0uCgoKIyBDb2RlIEFwcGVuZGl4CgpgYGB7ciByZWYubGFiZWw9a25pdHI6OmFsbF9sYWJlbHMoKSwgZWNobyA9IFQsIGV2YWwgPSBGfQpgYGAKCiMgTGl0ZXJhdHVyZSBDaXRlZAo=